1#![cfg_attr(feature = "nightly", feature(backtrace))]
2
3extern crate proc_macro;
4
5use anyhow::{anyhow, bail};
6use proc_macro::TokenStream;
7use proc_macro2::{Span, TokenStream as TokenStream2};
8use quote::{quote, ToTokens};
9use std::{iter, num::NonZeroU32};
10use syn::{
11 punctuated::Punctuated, Arm, Attribute, Block, Data, DataEnum, DataStruct, DeriveInput, Expr,
12 ExprMatch, Field, Fields, FieldsNamed, FieldsUnnamed, GenericParam, Generics, Ident, ItemConst,
13 ItemImpl, ItemStruct, Lit, LitInt, Member, Stmt, Token, Type, TypePath,
14};
15
16mod newtype;
17mod util;
18
19use util::{FieldAttributes, MessageAttributes, Result, WhereClauseBuilder};
20
21#[proc_macro_derive(Message, attributes(autoproto))]
22pub fn derive_message(input: TokenStream) -> TokenStream {
23 #[cfg(feature = "nightly")]
24 if cfg!(debug_assertions) {
25 std::panic::set_hook(Box::new(|_panic_info| {
26 eprintln!("{}", std::backtrace::Backtrace::capture());
27 }));
28 }
29
30 try_derive_message(input).unwrap().into()
31}
32
33#[proc_macro_derive(Proto, attributes(autoproto))]
34pub fn derive_proto(input: TokenStream) -> TokenStream {
35 try_derive_proto(input).unwrap().into()
36}
37
38#[proc_macro_derive(ProtoEncode, attributes(autoproto))]
39pub fn derive_protoencode(input: TokenStream) -> TokenStream {
40 try_derive_protoencode(input).unwrap().into()
41}
42
43#[proc_macro_derive(ProtoScalar, attributes(autoproto))]
44pub fn derive_protoscalar(input: TokenStream) -> TokenStream {
45 try_derive_protoscalar(input).unwrap().into()
46}
47
48#[proc_macro_derive(IsDefault, attributes(autoproto))]
49pub fn derive_is_default(input: TokenStream) -> TokenStream {
50 try_derive_is_default(input).unwrap().into()
51}
52
53fn derive_protoscalar_enum(
54 ident: &Ident,
55 generics: &Generics,
56 data: &DataEnum,
57) -> Result<TokenStream2> {
58 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
59
60 let variant_constants = data
61 .variants
62 .iter()
63 .enumerate()
64 .map::<Result<_>, _>(|(i, variant)| {
65 if variant.fields.is_empty() {
66 let variant_ident = &variant.ident;
67
68 let const_name = Ident::new(&format!("__TAG_{}", i), variant_ident.span().clone());
69
70 let item: ItemConst = syn::parse_quote!(
71 const #const_name: ::core::primitive::i32 = #ident::#variant_ident as ::core::primitive::i32;
72 );
73
74 Ok((const_name, variant_ident, item))
75 } else {
76 bail!("Cannot derive `protoscalar` for an enum with fields");
77 }
78 })
79 .collect::<Result<Vec<_>>>()?;
80
81 let constant_items = variant_constants
82 .iter()
83 .map(|(_, _, item)| item)
84 .collect::<Vec<_>>();
85
86 let match_arms = variant_constants
87 .iter()
88 .map::<Arm, _>(|(const_name, variant_ident, _)| syn::parse_quote!(#const_name => #ident :: #variant_ident))
89 .collect::<Punctuated<_, Token!(,)>>();
90
91 let (
92 protoscalar_impl,
93 is_default_impl,
94 protoencode_impl,
95 protoencoderepeated_impl,
96 protomergerepeated_impl,
97 proto_impl,
98 ): (ItemImpl, ItemImpl, ItemImpl, ItemImpl, ItemImpl, ItemImpl) = (
99 syn::parse_quote!(
100 impl #impl_generics ::autoproto::ProtoScalar for #ident #ty_generics #where_clause {
101 const DEFAULT_FIXED: ::autoproto::Fixed =
102 <::core::primitive::i32 as ::autoproto::ProtoScalar>::DEFAULT_FIXED;
103 const DEFAULT_VARINT: ::autoproto::Varint =
104 <::core::primitive::i32 as ::autoproto::ProtoScalar>::DEFAULT_VARINT;
105 const DEFAULT_ENCODING: ::autoproto::ScalarEncoding =
106 <::core::primitive::i32 as ::autoproto::ProtoScalar>::DEFAULT_ENCODING;
107
108 fn from_value(other: ::autoproto::Value) -> Option<Self> {
109 ::core::debug_assert_eq!(<Self as ::core::default::Default>::default() as i32, 0);
110
111 #(#constant_items)*
112
113 Some(match <::core::primitive::i32 as ::autoproto::ProtoScalar>::from_value(other)? {
114 #match_arms,
115 _ => return None,
116 })
117 }
118
119 fn to_value(&self) -> ::autoproto::Value {
120 ::core::debug_assert_eq!(<Self as ::core::default::Default>::default() as i32, 0);
121
122 <::core::primitive::i32 as ::autoproto::ProtoScalar>::to_value(
123 &(::core::clone::Clone::clone(self) as ::core::primitive::i32)
124 )
125 }
126 }
127 ),
128 syn::parse_quote!(
129 impl #impl_generics ::autoproto::IsDefault for #ident #ty_generics #where_clause {
130 fn is_default(&self) -> ::core::primitive::bool {
131 (::core::clone::Clone::clone(self) as ::core::primitive::i32) == 0
132 }
133 }
134 ),
135 syn::parse_quote!(
136 impl #impl_generics ::autoproto::ProtoEncode for #ident #ty_generics #where_clause {
137 fn encode_as_field(
138 &self,
139 tag: ::core::num::NonZeroU32,
140 buf: &mut dyn ::autoproto::prost::bytes::BufMut,
141 ) {
142 <
143 ::autoproto::MappedInt::<Self>
144 as ::autoproto::ProtoEncode
145 >::encode_as_field(
146 &::autoproto::MappedInt::new(::core::clone::Clone::clone(self)),
147 tag,
148 buf,
149 )
150 }
151
152 fn encoded_len_as_field(&self, tag: ::core::num::NonZeroU32) -> usize {
153 <
154 ::autoproto::MappedInt::<Self>
155 as ::autoproto::ProtoEncode
156 >::encoded_len_as_field(
157 &::autoproto::MappedInt::new(::core::clone::Clone::clone(self)),
158 tag,
159 )
160 }
161 }
162 ),
163 syn::parse_quote!(
164 impl #impl_generics ::autoproto::ProtoEncodeRepeated for #ident #ty_generics #where_clause {
165 fn encode_as_field_repeated<'__lifetime, I>(
166 iter: I,
167 tag: ::core::num::NonZeroU32,
168 buf: &mut dyn ::autoproto::bytes::BufMut,
169 )
170 where
171 I: ExactSizeIterator<Item = &'__lifetime Self> + Clone,
172 Self: '__lifetime,
173 {
174 ::autoproto::MappedInt::<Self>::encode_as_field_repeated(
175 iter,
176 tag,
177 buf,
178 );
179 }
180
181 fn encoded_len_as_field_repeated<'__lifetime, I>(iter: I, tag: ::core::num::NonZeroU32) -> usize
182 where
183 I: ExactSizeIterator<Item = &'__lifetime Self>,
184 Self: '__lifetime,
185 {
186 ::autoproto::MappedInt::<Self>::encoded_len_as_field_repeated(
187 iter,
188 tag,
189 )
190 }
191 }),
192 syn::parse_quote!(
193 impl #impl_generics ::autoproto::ProtoMergeRepeated for #ident #ty_generics #where_clause {
194 fn merge_repeated<T>(
195 values: &mut T,
196 wire_type: ::autoproto::prost::encoding::WireType,
197 buf: &mut dyn ::autoproto::bytes::Buf,
198 ctx: ::autoproto::prost::encoding::DecodeContext,
199 ) -> Result<(), ::autoproto::prost::DecodeError>
200 where
201 T: std::iter::Extend<Self>,
202 {
203 <::autoproto::MappedInt::<Self> as ::autoproto::ProtoMergeRepeated>::merge_repeated(
204 &mut ::autoproto::MapExtend::new(values, |::autoproto::MappedInt(i, _)| i),
205 wire_type,
206 buf,
207 ctx,
208 )
209 }
210 }
211 ),
212 syn::parse_quote!(
213 impl #impl_generics ::autoproto::Proto for #ident #ty_generics #where_clause {
214 fn merge_self(
215 &mut self,
216 wire_type: ::autoproto::prost::encoding::WireType,
217 buf: &mut dyn ::autoproto::prost::bytes::Buf,
218 ctx: ::autoproto::prost::encoding::DecodeContext,
219 ) -> Result<(), ::autoproto::prost::DecodeError> {
220 let mut mapped = ::autoproto::MappedInt::<Self>::new(::core::clone::Clone::clone(self));
221 ::autoproto::Proto::merge_self(&mut mapped, wire_type, buf, ctx)?;
222
223 *self = mapped.0;
224
225 Ok(())
226 }
227 }
228 ),
229 );
230
231 Ok(quote! {
232 #is_default_impl
233
234 #protoscalar_impl
235
236 #protoencode_impl
237
238 #proto_impl
239
240 #protoencoderepeated_impl
241
242 #protomergerepeated_impl
243 })
244}
245
246fn derive_protoscalar_struct(
247 ident: &Ident,
248 generics: &Generics,
249 data: &DataStruct,
250) -> Result<TokenStream2> {
251 let (impl_generics, ty_generics, _) = generics.split_for_impl();
252
253 let (inner_field, bracket) = {
254 let (fields, bracket): (_, fn(_) -> _) = match data {
255 DataStruct {
256 fields: Fields::Named(FieldsNamed { named: fields, .. }),
257 ..
258 } => (fields, |toks| quote!({ #toks })),
259 DataStruct {
260 fields:
261 Fields::Unnamed(FieldsUnnamed {
262 unnamed: fields, ..
263 }),
264 ..
265 } => (fields, |toks| quote!(( #toks ))),
266 DataStruct {
267 fields: Fields::Unit,
268 ..
269 } => {
270 bail!("`ProtoScalar` can only be implemented for `newtype` structs");
271 }
272 };
273
274 (
275 fields.first().ok_or_else(|| anyhow!("Programmer error"))?,
276 bracket,
277 )
278 };
279
280 let field: Member = inner_field
281 .ident
282 .clone()
283 .map(Member::Named)
284 .unwrap_or_else(|| Member::Unnamed(0.into()));
285
286 let mut where_clause_builder = WhereClauseBuilder::new(generics);
287 let (
288 is_default_impl,
289 protoscalar_impl,
290 protoencode_impl,
291 proto_impl,
292 protoencoderepeated_impl,
293 protomergerepeated_impl,
294 ) = (
295 newtype::is_default(
296 ident,
297 &field,
298 &impl_generics,
299 &ty_generics,
300 &mut where_clause_builder,
301 ),
302 newtype::protoscalar(
303 ident,
304 &field,
305 &inner_field.ty,
306 bracket,
307 &impl_generics,
308 &ty_generics,
309 &mut where_clause_builder,
310 ),
311 newtype::protoencode(
312 ident,
313 &field,
314 &impl_generics,
315 &ty_generics,
316 &mut where_clause_builder,
317 ),
318 newtype::proto(
319 ident,
320 &field,
321 &impl_generics,
322 &ty_generics,
323 &mut where_clause_builder,
324 ),
325 newtype::protoencoderepeated(
326 ident,
327 &field,
328 &inner_field.ty,
329 &impl_generics,
330 &ty_generics,
331 &mut where_clause_builder,
332 ),
333 newtype::protomergerepeated(
334 ident,
335 &field,
336 &inner_field.ty,
337 bracket,
338 &impl_generics,
339 &ty_generics,
340 &mut where_clause_builder,
341 ),
342 );
343
344 Ok(quote! {
345 #is_default_impl
346
347 #protoscalar_impl
348
349 #protoencode_impl
350
351 #proto_impl
352
353 #protoencoderepeated_impl
354
355 #protomergerepeated_impl
356 })
357}
358
359fn try_derive_protoscalar(input: TokenStream) -> Result<TokenStream2> {
360 let input: DeriveInput = syn::parse(input)?;
361 let DeriveInput {
362 attrs: _,
363 vis: _,
364 ident,
365 generics,
366 data,
367 } = &input;
368
369 match data {
370 Data::Struct(data) => derive_protoscalar_struct(ident, generics, data),
371 Data::Enum(data) => derive_protoscalar_enum(ident, generics, data),
372 Data::Union(_) => bail!("Cannot derive `ProtoScalar` for an untagged union"),
373 }
374}
375
376fn try_derive_is_default(input: TokenStream) -> Result<TokenStream2> {
377 let input: DeriveInput = syn::parse(input)?;
378 let DeriveInput {
379 attrs,
380 vis: _,
381 ident,
382 generics,
383 data,
384 } = &input;
385
386 let attrs = MessageAttributes::new(attrs)?;
387
388 let (impl_generics, ty_generics, _) = generics.split_for_impl();
389 if attrs.transparent {
390 let inner_field = match data {
391 Data::Struct(DataStruct {
392 fields: Fields::Named(FieldsNamed { named: fields, .. }),
393 ..
394 })
395 | Data::Struct(DataStruct {
396 fields:
397 Fields::Unnamed(FieldsUnnamed {
398 unnamed: fields, ..
399 }),
400 ..
401 }) => {
402 if fields.len() != 1 {
403 bail!("`transparent` message must have exactly one field");
404 }
405
406 fields.first().ok_or_else(|| anyhow!("Programmer error"))?
407 }
408 Data::Struct(DataStruct {
409 fields: Fields::Unit,
410 ..
411 }) => {
412 bail!("Cannot have a `transparent` message without fields");
413 }
414 _ => {
415 bail!("Invalid type for a `transparent` message");
416 }
417 };
418
419 let field: Member = inner_field
420 .ident
421 .clone()
422 .map(Member::Named)
423 .unwrap_or_else(|| Member::Unnamed(0.into()));
424
425 let mut where_clause_builder = WhereClauseBuilder::new(generics);
426 let is_default_impl = newtype::is_default(
427 ident,
428 &field,
429 &impl_generics,
430 &ty_generics,
431 &mut where_clause_builder,
432 );
433
434 Ok(quote! { #is_default_impl })
435 } else {
436 let where_clause_builder = WhereClauseBuilder::new(&generics);
437 let where_clause = where_clause_builder
438 .with_self_bound(quote!(::core::default::Default + ::core::cmp::PartialEq));
439
440 Ok(quote! {
441 impl #impl_generics ::autoproto::IsDefault for #ident #ty_generics
442 #where_clause
443 {
444 fn is_default(&self) -> bool {
445 ::autoproto::generic::default::is_default(self)
446 }
447 }
448 })
449 }
450}
451
452enum DeriveMode {
453 ImmutableOnly,
454 ImmutableAndMutable,
455}
456
457impl Default for DeriveMode {
458 fn default() -> Self {
459 Self::ImmutableAndMutable
460 }
461}
462
463fn try_derive_protoencode(input: TokenStream) -> Result<TokenStream2> {
464 let input: DeriveInput = syn::parse(input)?;
465 let DeriveInput {
466 attrs,
467 vis: _,
468 ident,
469 generics,
470 data,
471 } = &input;
472
473 let attrs = MessageAttributes::new(attrs)?;
474
475 if attrs.transparent {
476 let inner_field = match data {
477 Data::Struct(DataStruct {
478 fields: Fields::Named(FieldsNamed { named: fields, .. }),
479 ..
480 })
481 | Data::Struct(DataStruct {
482 fields:
483 Fields::Unnamed(FieldsUnnamed {
484 unnamed: fields, ..
485 }),
486 ..
487 }) => {
488 if fields.len() != 1 {
489 bail!("`transparent` message must have exactly one field");
490 }
491
492 fields.first().ok_or_else(|| anyhow!("Programmer error"))?
493 }
494 Data::Struct(DataStruct {
495 fields: Fields::Unit,
496 ..
497 }) => {
498 bail!("Cannot have a `transparent` message without fields");
499 }
500 _ => {
501 bail!("Invalid type for a `transparent` message");
502 }
503 };
504
505 let (impl_generics, ty_generics, _) = generics.split_for_impl();
506 let field: Member = inner_field
507 .ident
508 .clone()
509 .map(Member::Named)
510 .unwrap_or_else(|| Member::Unnamed(0.into()));
511
512 let mut where_clause_builder = WhereClauseBuilder::new(generics);
513 let protoencode_impl = newtype::protoencode(
514 ident,
515 &field,
516 &impl_generics,
517 &ty_generics,
518 &mut where_clause_builder,
519 );
520
521 Ok(quote! { #protoencode_impl })
522 } else {
523 match data {
524 Data::Struct(DataStruct {
525 fields: Fields::Named(FieldsNamed { named: fields, .. }),
526 ..
527 })
528 | Data::Struct(DataStruct {
529 fields:
530 Fields::Unnamed(FieldsUnnamed {
531 unnamed: fields, ..
532 }),
533 ..
534 }) => {
535 let protostruct_impl = try_derive_protostruct(
536 fields.into_iter(),
537 ident,
538 generics,
539 DeriveMode::ImmutableOnly,
540 )?;
541
542 let (impl_generics, ty_generics, _) = generics.split_for_impl();
543
544 let protoencode_impl = impl_protoencode_for_protostruct(
545 ident,
546 &impl_generics,
547 &ty_generics,
548 &mut WhereClauseBuilder::new(generics),
549 );
550
551 Ok(quote!(
552 #protostruct_impl
553 #protoencode_impl
554 ))
555 }
556 Data::Union(..) => {
557 bail!("Message can not be derived for an untagged union (try using `enum`)")
558 }
559 _ => {
560 bail!("Currently unsupported type for `derive(ProtoEncode)`")
561 }
562 }
563 }
564}
565
566fn try_derive_message(input: TokenStream) -> Result<TokenStream2> {
567 let input: DeriveInput = syn::parse(input)?;
568 let DeriveInput {
569 attrs,
570 vis: _,
571 ident,
572 generics,
573 data,
574 } = &input;
575
576 match data {
577 Data::Struct(data) => try_derive_message_for_struct(attrs, ident, generics, data),
578 Data::Enum(data) => try_derive_oneof(attrs, ident, generics, data),
579 Data::Union(..) => {
580 bail!("Message can not be derived for an untagged union (try using `enum`)")
581 }
582 }
583}
584
585fn try_derive_proto(input: TokenStream) -> Result<TokenStream2> {
586 let input: DeriveInput = syn::parse(input)?;
587 let DeriveInput {
588 attrs,
589 vis: _,
590 ident,
591 generics,
592 data,
593 } = &input;
594
595 match data {
596 Data::Struct(data) => try_derive_proto_for_struct(attrs, ident, generics, data),
597 Data::Enum(..) => todo!(),
598 Data::Union(..) => {
599 bail!("Message can not be derived for an untagged union (try using `enum`)")
600 }
601 }
602}
603
604fn try_derive_oneof(
605 _attrs: &[Attribute],
606 ident: &Ident,
607 generics: &Generics,
608 data: &DataEnum,
609) -> Result<TokenStream2> {
610 fn make_variant_get_field_arm_with_fields<F, T, FIter>(
611 ident: &Ident,
612 tag: &Lit,
613 generics: &Generics,
614 mut brackets: F,
615 semicolon: Option<Token!(;)>,
616 fields: &FIter,
617 ) -> Arm
618 where
619 F: FnMut(TokenStream2) -> T,
620 T: ToTokens,
621 for<'a> &'a FIter: IntoIterator<Item = &'a Field>,
622 {
623 let names = fields
624 .into_iter()
625 .enumerate()
626 .map(|(i, field)| {
627 field
628 .ident
629 .clone()
630 .unwrap_or_else(|| Ident::new(&format!("__field_{}", i), Span::call_site()))
631 })
632 .collect::<Punctuated<_, Token!(,)>>();
633
634 let make_refs = names
635 .iter()
636 .map::<Expr, _>(|name| syn::parse_quote!(::autoproto::generic::Wrapper(#name)))
637 .collect::<Punctuated<_, Token!(,)>>();
638
639 let make_refs: Stmt = syn::parse_quote!(let (#names) = (#make_refs););
640
641 let (typarams, dummy_fields): (Vec<Ident>, Punctuated<_, Token!(,)>) = fields
642 .into_iter()
643 .cloned()
644 .enumerate()
645 .map(|(i, field)| {
646 let tyident = Ident::new(&format!("__Ty{}", i), Span::call_site());
647 let ty = Type::Path(TypePath {
648 qself: None,
649 path: tyident.clone().into(),
650 });
651
652 (tyident, Field { ty, ..field })
653 })
654 .unzip();
655
656 let dummy_generics = Generics {
657 params: typarams
658 .into_iter()
659 .map(|name| GenericParam::Type(name.into()))
660 .collect(),
661 where_clause: None,
662 ..generics.clone()
663 };
664
665 let struct_body = brackets(quote!(#dummy_fields));
666 let variant_bindings = brackets(quote!(#names));
667
668 syn::parse_quote!(
669 Self::#ident #variant_bindings => {
670 #[derive(::autoproto::ProtoEncode)]
671 struct #ident #dummy_generics #struct_body #semicolon
672
673 #make_refs
674
675 __proto_arg_func(
676 &#ident #variant_bindings,
677 unsafe { ::core::num::NonZeroU32::new_unchecked(#tag) },
678 )
679 }
680 )
681 }
682
683 fn make_unit_variant_get_field_arm<T: ToTokens>(ident: &Ident, tag: &Lit, brackets: T) -> Arm {
684 syn::parse_quote!(
685 Self::#ident #brackets => __proto_arg_func(
686 &(),
687 unsafe { ::core::num::NonZeroU32::new_unchecked(#tag) },
688 )
689 )
690 }
691
692 fn make_newtype_variant_get_field_arm<F, T>(
693 ident: &Ident,
694 tag: &Lit,
695 field_name: Ident,
696 brackets: F,
697 ) -> Arm
698 where
699 F: FnOnce(TokenStream2) -> T,
700 T: ToTokens,
701 {
702 let field_name_pat = brackets(quote!(#field_name));
703
704 syn::parse_quote!(
705 Self::#ident #field_name_pat => __proto_arg_func(
706 #field_name,
707 unsafe { ::core::num::NonZeroU32::new_unchecked(#tag) },
708 )
709 )
710 }
711
712 fn make_variant_get_field_arm(
713 ident: &Ident,
714 tag: &Lit,
715 generics: &Generics,
716 fields: &Fields,
717 ) -> Arm {
718 match &fields {
719 Fields::Named(FieldsNamed { named: fields, .. }) => match fields.len() {
720 0 => make_unit_variant_get_field_arm(ident, tag, quote!({})),
721 1 => {
722 let field_name = fields
723 .first()
724 .and_then(|field| field.ident.clone())
725 .expect("Programmer error: names array should have one named element");
726
727 make_newtype_variant_get_field_arm(ident, tag, field_name, |f| quote!( { #f } ))
728 }
729 _ => make_variant_get_field_arm_with_fields(
730 ident,
731 tag,
732 generics,
733 |val| quote!( { #val } ),
734 None,
735 fields,
736 ),
737 },
738 Fields::Unnamed(FieldsUnnamed {
739 unnamed: fields, ..
740 }) => match fields.len() {
741 0 => make_unit_variant_get_field_arm(ident, tag, quote!(())),
742 1 => {
743 let field_name = Ident::new("__proto_enum_inner", Span::call_site());
744
745 make_newtype_variant_get_field_arm(ident, tag, field_name, |f| quote!( ( #f ) ))
746 }
747 _ => make_variant_get_field_arm_with_fields(
748 ident,
749 tag,
750 generics,
751 |val| quote!( ( #val ) ),
752 Some(Default::default()),
753 fields,
754 ),
755 },
756 Fields::Unit => make_unit_variant_get_field_arm(ident, tag, quote!()),
757 }
758 }
759
760 fn make_variant_exec_merge_arm_with_fields<F, T, FIter>(
761 ident: &Ident,
762 tag: &Lit,
763 generics: &Generics,
764 mut brackets: F,
765 semicolon: Option<Token!(;)>,
766 fields: &FIter,
767 ) -> Arm
768 where
769 F: FnMut(TokenStream2) -> T,
770 T: ToTokens,
771 for<'a> &'a FIter: IntoIterator<Item = &'a Field>,
772 {
773 let names = fields
774 .into_iter()
775 .enumerate()
776 .map(|(i, field)| {
777 field
778 .ident
779 .clone()
780 .unwrap_or_else(|| Ident::new(&format!("__field_{}", i), Span::call_site()))
781 })
782 .collect::<Punctuated<_, Token!(,)>>();
783
784 let (typarams, dummy_fields): (Vec<Ident>, Punctuated<_, Token!(,)>) = fields
785 .into_iter()
786 .cloned()
787 .enumerate()
788 .map(|(i, field)| {
789 let tyident = Ident::new(&format!("__Ty{}", i), Span::call_site());
790 let ty = Type::Path(TypePath {
791 qself: None,
792 path: tyident.clone().into(),
793 });
794
795 (tyident, Field { ty, ..field })
796 })
797 .unzip();
798
799 let dummy_generics = Generics {
800 params: typarams
801 .into_iter()
802 .map(|name| GenericParam::Type(name.into()))
803 .collect(),
804 where_clause: None,
805 ..generics.clone()
806 };
807
808 let struct_body = brackets(quote!(
809 #dummy_fields,
810 ));
811 let ref_mut_construct: Stmt = {
812 let construct = names
813 .iter()
814 .map::<Expr, _>(|name| syn::parse_quote!(::autoproto::generic::Wrapper(#name)))
815 .collect::<Punctuated<_, Token!(,)>>();
816 syn::parse_quote!(let (#names) = (#construct);)
817 };
818 let owned_construct: Stmt = {
819 let default: Expr = syn::parse_quote!(::core::default::Default::default());
820
821 let construct = names
822 .iter()
823 .map(|_| default.clone())
824 .collect::<Punctuated<_, Token!(,)>>();
825 syn::parse_quote!(let (#names) = (#construct);)
826 };
827 let variant_bindings = brackets(quote!(#names));
828
829 let (dummy_impl_generics, dummy_ty_generics, _) = dummy_generics.split_for_impl();
830
831 let where_clause_builder = WhereClauseBuilder::new(&dummy_generics);
832 let clear_where_clause = where_clause_builder.with_bound(quote!(::autoproto::Clear));
833
834 let deconstruct_dummy = brackets(quote!(#names));
835
836 let clear_all = Block {
837 brace_token: syn::token::Brace {
838 span: Span::call_site(),
839 },
840 stmts: names
841 .iter()
842 .map::<Stmt, _>(|name| syn::parse_quote!(::autoproto::Clear::clear(#name);))
843 .collect(),
844 };
845
846 let (dummy_struct_def, dummy_clear_impl): (ItemStruct, ItemImpl) = (
847 syn::parse_quote!(
848 #[derive(::autoproto::Proto)]
849 struct #ident #dummy_generics #struct_body #semicolon
850 ),
851 syn::parse_quote!(
852 impl #dummy_impl_generics ::autoproto::Clear for #ident #dummy_ty_generics
853 #clear_where_clause
854 {
855 fn clear(&mut self) {
856 let Self #deconstruct_dummy = self;
857
858 #clear_all
859 }
860 }
861 ),
862 );
863
864 syn::parse_quote!(
865 #tag => {
866 #dummy_struct_def
867
868 #dummy_clear_impl
869
870 match self {
871 Self :: #ident #variant_bindings => {
872 #ref_mut_construct
873
874 let mut __proto_dummy_struct = #ident #variant_bindings;
875
876 __proto_arg_func(&mut __proto_dummy_struct)
877 }
878 _ => {
879 #owned_construct
880
881 let mut __proto_dummy_struct = #ident #variant_bindings;
882
883 let out = __proto_arg_func(&mut __proto_dummy_struct);
884
885 let #ident #deconstruct_dummy = __proto_dummy_struct;
886
887 *self = Self::#ident #variant_bindings;
888
889 out
890 }
891 }
892 }
893 )
894 }
895
896 fn make_unit_variant_exec_merge_arm(tag: &Lit) -> Arm {
897 syn::parse_quote!(
898 #tag => __proto_arg_func(&mut ())
899 )
900 }
901
902 fn make_newtype_variant_exec_merge_arm<F, T>(
903 ident: &Ident,
904 tag: &Lit,
905 field_name: Option<Ident>,
906 brackets: F,
907 ) -> Arm
908 where
909 F: FnOnce(TokenStream2) -> T,
910 T: ToTokens,
911 {
912 let name = Ident::new("__proto_new_inner", Span::call_site());
913
914 let field_spec = field_name.map(|name| quote!(#name :));
915
916 let construct_variant = brackets(quote!(#field_spec #name));
917
918 syn::parse_quote!(
919 #tag => {
920 let mut #name = Default::default();
921
922 let out = __proto_arg_func(&mut #name);
923
924 *self = Self::#ident #construct_variant;
925
926 out
927 }
928 )
929 }
930
931 fn make_variant_exec_merge_arm(
932 ident: &Ident,
933 tag: &Lit,
934 generics: &Generics,
935 fields: &Fields,
936 ) -> Arm {
937 match &fields {
938 Fields::Named(FieldsNamed { named: fields, .. }) => match fields.len() {
939 0 => make_unit_variant_exec_merge_arm(tag),
940 1 => {
941 let field_name = fields
942 .first()
943 .and_then(|field| field.ident.clone())
944 .expect("Programmer error: names array should have one named element");
945
946 make_newtype_variant_exec_merge_arm(
947 ident,
948 tag,
949 Some(field_name),
950 |f| quote!( { #f } ),
951 )
952 }
953 _ => make_variant_exec_merge_arm_with_fields(
954 ident,
955 tag,
956 generics,
957 |val| quote!( { #val } ),
958 None,
959 fields,
960 ),
961 },
962 Fields::Unnamed(FieldsUnnamed {
963 unnamed: fields, ..
964 }) => match fields.len() {
965 0 => make_unit_variant_exec_merge_arm(tag),
966 1 => make_newtype_variant_exec_merge_arm(ident, tag, None, |f| quote!( ( #f ) )),
967 _ => make_variant_exec_merge_arm_with_fields(
968 ident,
969 tag,
970 generics,
971 |val| quote!( ( #val ) ),
972 Some(Default::default()),
973 fields,
974 ),
975 },
976 Fields::Unit => make_unit_variant_exec_merge_arm(tag),
977 }
978 }
979
980 let mut explicitly_tagged = None::<bool>;
981
982 let variants = data
983 .variants
984 .iter()
985 .enumerate()
986 .map(|(i, variant)| {
987 let attributes = FieldAttributes::new(&variant.attrs)?;
988
989 match (explicitly_tagged, &attributes.tag) {
990 (None, _) | (Some(true), Some(_)) | (Some(false), None) => {}
991 (Some(true), None) | (Some(false), Some(_)) => {
992 return Err(anyhow!(
993 "If `tag` is specified for one field it must be specified for all fields"
994 ));
995 }
996 }
997
998 explicitly_tagged = Some(attributes.tag.is_some());
999
1000 let tag = attributes
1001 .tag
1002 .unwrap_or_else(|| NonZeroU32::new(i as u32 + 1).unwrap());
1003 let tag: Lit = LitInt::new(&tag.get().to_string(), Span::call_site()).into();
1004
1005 Ok((tag, variant))
1006 })
1007 .collect::<Result<Vec<_>>>()?;
1008
1009 let (impl_generics, ty_generics, _) = generics.split_for_impl();
1010
1011 let variant_get_field: Vec<Arm> = variants
1012 .iter()
1013 .map::<Arm, _>(|(tag, variant)| {
1014 make_variant_get_field_arm(&variant.ident, tag, generics, &variant.fields)
1015 })
1016 .collect();
1017
1018 let variant_exec_merge: Vec<Arm> = variants
1019 .iter()
1020 .map::<Arm, _>(|(tag, variant)| {
1021 make_variant_exec_merge_arm(&variant.ident, tag, generics, &variant.fields)
1022 })
1023 .chain(iter::once(
1024 syn::parse_quote!(_ => { return ::core::option::Option::<__FuncOut>::None; }),
1025 ))
1026 .collect();
1027
1028 let where_clause_builder = WhereClauseBuilder::new(generics);
1029
1030 let get_variant = ExprMatch {
1031 attrs: vec![],
1032 match_token: Default::default(),
1033 expr: syn::parse_quote!(self),
1034 brace_token: Default::default(),
1035 arms: variant_get_field,
1036 };
1037
1038 let exec_merge = ExprMatch {
1039 attrs: vec![],
1040 match_token: Default::default(),
1041 expr: syn::parse_quote!(::core::num::NonZeroU32::get(tag)),
1042 brace_token: Default::default(),
1043 arms: variant_exec_merge,
1044 };
1045
1046 let message_where_clause = where_clause_builder.with_self_bound(quote!(
1047 ::autoproto::ProtoOneof
1048 + ::autoproto::Clear
1049 + ::core::fmt::Debug
1050 + ::core::marker::Send
1051 + ::core::marker::Sync
1052 ));
1053 let message_impl = impl_message_for_protooneof(
1054 ident,
1055 &impl_generics,
1056 &ty_generics,
1057 Some(&message_where_clause),
1058 );
1059
1060 let protooneof_where_clause = where_clause_builder.with_bound(quote!(
1061 ::core::default::Default + ::autoproto::Proto + ::autoproto::Clear
1062 ));
1063
1064 Ok(quote!(
1065 impl #impl_generics ::autoproto::ProtoOneof for #ident #ty_generics
1066 #protooneof_where_clause
1067 {
1068 fn variant<__Func, __FuncOut>(&self, __proto_arg_func: __Func) -> __FuncOut
1069 where
1070 __Func: ::core::ops::FnOnce(&(dyn ::autoproto::ProtoEncode + '_), ::core::num::NonZeroU32) -> __FuncOut
1071 {
1072 #get_variant
1073 }
1074
1075 fn exec_merge<__Func, __FuncOut>(&mut self, tag: ::core::num::NonZeroU32, __proto_arg_func: __Func) -> Option<__FuncOut>
1076 where
1077 __Func: ::core::ops::FnOnce(&mut (dyn ::autoproto::Proto + '_)) -> __FuncOut
1078 {
1079 ::core::option::Option::<__FuncOut>::Some(#exec_merge)
1080 }
1081 }
1082
1083 impl #impl_generics ::autoproto::IsMessage for #ident #ty_generics #protooneof_where_clause {}
1084
1085 #message_impl
1086 ))
1087}
1088
1089fn try_derive_protostruct<'a>(
1090 fields: impl ExactSizeIterator<Item = &'a Field>,
1091 ident: &Ident,
1092 generics: &Generics,
1093 mode: DeriveMode,
1094) -> Result<TokenStream2> {
1095 let (impl_generics, ty_generics, _) = generics.split_for_impl();
1096
1097 let num_fields = fields.len();
1098
1099 let mut explicitly_tagged = None::<bool>;
1100
1101 let fields: Result<Vec<(NonZeroU32, Member)>> = fields
1102 .enumerate()
1103 .map(|(i, field)| {
1104 let attributes = FieldAttributes::new(&field.attrs)?;
1105
1106 match (explicitly_tagged, &attributes.tag) {
1107 (None, _) | (Some(true), Some(_)) | (Some(false), None) => {}
1108 (Some(true), None) | (Some(false), Some(_)) => {
1109 return Err(anyhow!(
1110 "If `tag` is specified for one field it must be specified for all fields"
1111 ));
1112 }
1113 }
1114
1115 explicitly_tagged = Some(attributes.tag.is_some());
1116
1117 Ok((
1118 attributes
1119 .tag
1120 .unwrap_or_else(|| NonZeroU32::new(i as u32 + 1).unwrap()),
1121 field
1122 .ident
1123 .clone()
1124 .map(Member::Named)
1125 .unwrap_or_else(|| Member::Unnamed(i.into())),
1126 ))
1127 })
1128 .collect();
1129 let fields = fields?;
1130
1131 let fields_array: Punctuated<_, Token!(,)> = fields
1132 .iter()
1133 .map(|(tag, member)| {
1134 let tag: Lit = LitInt::new(&tag.get().to_string(), Span::call_site()).into();
1135
1136 quote!(
1137 (
1138 unsafe { ::core::num::NonZeroU32::new_unchecked(#tag) },
1139 &self.#member as &dyn ::autoproto::ProtoEncode,
1140 )
1141 )
1142 })
1143 .collect();
1144
1145 let get_field_mut: Punctuated<_, Token!(,)> = fields
1146 .into_iter()
1147 .map::<Arm, _>(|(tag, member)| {
1148 let tag: Lit = LitInt::new(&tag.get().to_string(), Span::call_site()).into();
1149
1150 syn::parse_quote!(#tag => &mut self.#member)
1151 })
1152 .chain(iter::once(syn::parse_quote!(_ => { return None; })))
1153 .collect();
1154
1155 let where_clause_builder = WhereClauseBuilder::new(generics);
1156
1157 let protostruct_where_clause =
1158 where_clause_builder.with_bound(quote!(::autoproto::ProtoEncode));
1159 let protostructmut_where_clause = where_clause_builder
1160 .with_bound(quote!(::autoproto::Proto))
1161 .with_self_bound(quote!(::autoproto::ProtoStruct));
1162
1163 let immut: ItemImpl = syn::parse_quote! {
1164 impl #impl_generics ::autoproto::ProtoStruct for #ident #ty_generics #protostruct_where_clause {
1165 type Fields<'__field_lifetime>
1166 where
1167 Self: '__field_lifetime
1168 = [
1169 (
1170 ::core::num::NonZeroU32,
1171 &'__field_lifetime (dyn ::autoproto::ProtoEncode + '__field_lifetime),
1172 );
1173 #num_fields
1174 ];
1175
1176 fn fields(&self) -> Self::Fields<'_> {
1177 [#fields_array]
1178 }
1179 }
1180 };
1181 let mutable: Option<ItemImpl> = match mode {
1182 DeriveMode::ImmutableOnly => None,
1183 DeriveMode::ImmutableAndMutable => Some(syn::parse_quote! {
1184 impl #impl_generics ::autoproto::ProtoStructMut for #ident #ty_generics
1185 #protostructmut_where_clause
1186 {
1187 fn field_mut(&mut self, tag: ::core::num::NonZeroU32) -> Option<&mut dyn ::autoproto::Proto> {
1188 Some(match ::core::num::NonZeroU32::get(tag) {
1189 #get_field_mut
1190 })
1191 }
1192 }
1193 }),
1194 };
1195
1196 Ok(quote! {
1197 impl #impl_generics ::autoproto::IsMessage for #ident #ty_generics #protostruct_where_clause {}
1198
1199 #immut
1200
1201 #mutable
1202 })
1203}
1204
1205fn try_derive_proto_for_struct(
1206 attrs: &[Attribute],
1207 ident: &Ident,
1208 generics: &Generics,
1209 data: &DataStruct,
1210) -> Result<TokenStream2> {
1211 let attrs = MessageAttributes::new(attrs)?;
1212
1213 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
1214
1215 let mut where_clause_builder = WhereClauseBuilder::new(generics);
1216
1217 if attrs.transparent {
1218 let inner_field = match data {
1219 DataStruct {
1220 fields: Fields::Named(FieldsNamed { named: fields, .. }),
1221 ..
1222 }
1223 | DataStruct {
1224 fields:
1225 Fields::Unnamed(FieldsUnnamed {
1226 unnamed: fields, ..
1227 }),
1228 ..
1229 } => {
1230 if fields.len() != 1 {
1231 bail!("`transparent` message must have exactly one field");
1232 }
1233
1234 fields.first().ok_or_else(|| anyhow!("Programmer error"))?
1235 }
1236 DataStruct {
1237 fields: Fields::Unit,
1238 ..
1239 } => {
1240 bail!("Cannot have a `transparent` message without fields");
1241 }
1242 };
1243
1244 let field: Member = inner_field
1245 .ident
1246 .clone()
1247 .map(Member::Named)
1248 .unwrap_or_else(|| Member::Unnamed(0.into()));
1249
1250 let mut where_clause_builder = WhereClauseBuilder::new(generics);
1251
1252 let (protoencode_impl, proto_impl) = (
1253 newtype::protoencode(
1254 ident,
1255 &field,
1256 &impl_generics,
1257 &ty_generics,
1258 &mut where_clause_builder,
1259 ),
1260 newtype::proto(
1261 ident,
1262 &field,
1263 &impl_generics,
1264 &ty_generics,
1265 &mut where_clause_builder,
1266 ),
1267 );
1268
1269 Ok(quote! {
1270 #protoencode_impl
1271 #proto_impl
1272 })
1273 } else {
1274 match data {
1275 DataStruct {
1276 fields: Fields::Named(FieldsNamed { named: fields, .. }),
1277 ..
1278 }
1279 | DataStruct {
1280 fields:
1281 Fields::Unnamed(FieldsUnnamed {
1282 unnamed: fields, ..
1283 }),
1284 ..
1285 } => {
1286 if fields.is_empty() {
1287 Ok(unit_proto_impl(
1288 ident,
1289 impl_generics,
1290 ty_generics,
1291 where_clause,
1292 ))
1293 } else {
1294 let protostruct_impl = try_derive_protostruct(
1295 fields.into_iter(),
1296 ident,
1297 generics,
1298 Default::default(),
1299 )?;
1300
1301 let proto_impl = impl_proto_for_protostruct(
1302 ident,
1303 &impl_generics,
1304 &ty_generics,
1305 &mut where_clause_builder,
1306 );
1307
1308 Ok(quote!(
1309 #protostruct_impl
1310
1311 #proto_impl
1312 ))
1313 }
1314 }
1315 DataStruct {
1316 fields: Fields::Unit,
1317 ..
1318 } => Ok(unit_proto_impl(
1319 ident,
1320 impl_generics,
1321 ty_generics,
1322 where_clause,
1323 )),
1324 }
1325 }
1326}
1327
1328fn try_derive_message_for_struct(
1329 attrs: &[Attribute],
1330 ident: &Ident,
1331 generics: &Generics,
1332 data: &DataStruct,
1333) -> Result<TokenStream2> {
1334 let attrs = MessageAttributes::new(attrs)?;
1335
1336 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
1337
1338 let where_clause_builder = WhereClauseBuilder::new(generics);
1339
1340 if attrs.transparent {
1341 let inner_field = match data {
1342 DataStruct {
1343 fields: Fields::Named(FieldsNamed { named: fields, .. }),
1344 ..
1345 }
1346 | DataStruct {
1347 fields:
1348 Fields::Unnamed(FieldsUnnamed {
1349 unnamed: fields, ..
1350 }),
1351 ..
1352 } => {
1353 if fields.len() != 1 {
1354 bail!("`transparent` message must have exactly one field");
1355 }
1356
1357 fields.first().ok_or_else(|| anyhow!("Programmer error"))?
1358 }
1359 DataStruct {
1360 fields: Fields::Unit,
1361 ..
1362 } => {
1363 bail!("Cannot have a `transparent` message without fields");
1364 }
1365 };
1366
1367 let field: Member = inner_field
1368 .ident
1369 .clone()
1370 .map(Member::Named)
1371 .unwrap_or_else(|| Member::Unnamed(0.into()));
1372
1373 let mut where_clause_builder = WhereClauseBuilder::new(generics);
1374
1375 let (protoencode_impl, proto_impl, message_impl) = (
1376 newtype::protoencode(
1377 ident,
1378 &field,
1379 &impl_generics,
1380 &ty_generics,
1381 &mut where_clause_builder,
1382 ),
1383 newtype::proto(
1384 ident,
1385 &field,
1386 &impl_generics,
1387 &ty_generics,
1388 &mut where_clause_builder,
1389 ),
1390 newtype::message(
1391 ident,
1392 &field,
1393 &impl_generics,
1394 &ty_generics,
1395 &mut where_clause_builder,
1396 ),
1397 );
1398
1399 Ok(quote! {
1400 #protoencode_impl
1401 #proto_impl
1402 #message_impl
1403 })
1404 } else {
1405 match data {
1406 DataStruct {
1407 fields: Fields::Named(FieldsNamed { named: fields, .. }),
1408 ..
1409 }
1410 | DataStruct {
1411 fields:
1412 Fields::Unnamed(FieldsUnnamed {
1413 unnamed: fields, ..
1414 }),
1415 ..
1416 } => {
1417 if fields.is_empty() {
1418 Ok(unit_proto_impl(
1419 ident,
1420 impl_generics,
1421 ty_generics,
1422 where_clause,
1423 ))
1424 } else {
1425 let protostruct_impl = try_derive_protostruct(
1426 fields.into_iter(),
1427 ident,
1428 generics,
1429 Default::default(),
1430 )?;
1431
1432 let message_where_clause = where_clause_builder.with_self_bound(quote!(
1433 ::autoproto::ProtoStructMut
1434 + ::autoproto::Clear
1435 + ::core::fmt::Debug
1436 + ::core::marker::Send
1437 + ::core::marker::Sync
1438 ));
1439 let message_impl = impl_message_for_protostruct(
1440 ident,
1441 &impl_generics,
1442 &ty_generics,
1443 Some(&message_where_clause),
1444 );
1445
1446 Ok(quote!(
1447 #protostruct_impl
1448
1449 #message_impl
1450 ))
1451 }
1452 }
1453 DataStruct {
1454 fields: Fields::Unit,
1455 ..
1456 } => Ok(unit_proto_impl(
1457 ident,
1458 impl_generics,
1459 ty_generics,
1460 where_clause,
1461 )),
1462 }
1463 }
1464}
1465
1466fn impl_message_for_protooneof(
1467 ident: &Ident,
1468 impl_generics: &syn::ImplGenerics,
1469 ty_generics: &syn::TypeGenerics,
1470 where_clause: Option<&syn::WhereClause>,
1471) -> ItemImpl {
1472 syn::parse_quote!(
1473 impl #impl_generics ::autoproto::prost::Message for #ident #ty_generics #where_clause
1474 {
1475 fn encode_raw<__Buffer>(&self, buf: &mut __Buffer)
1476 where
1477 __Buffer: ::autoproto::prost::bytes::BufMut,
1478 {
1479 ::autoproto::generic::protooneof::message_encode_raw(self, buf)
1480 }
1481
1482 fn merge_field<__Buffer: ::autoproto::prost::bytes::Buf>(
1483 &mut self,
1484 tag: u32,
1485 wire_type: ::autoproto::prost::encoding::WireType,
1486 buf: &mut __Buffer,
1487 ctx: ::autoproto::prost::encoding::DecodeContext,
1488 ) -> Result<(), ::autoproto::prost::DecodeError> {
1489 ::autoproto::generic::protooneof::message_merge_field(self, tag, wire_type, buf, ctx)
1490 }
1491
1492 fn encoded_len(&self) -> usize {
1493 ::autoproto::generic::protooneof::message_encoded_len(self)
1494 }
1495
1496 fn clear(&mut self) {
1497 ::autoproto::generic::clear::message_clear(self)
1498 }
1499 }
1500 )
1501}
1502
1503fn impl_message_for_protostruct(
1504 ident: &Ident,
1505 impl_generics: &syn::ImplGenerics,
1506 ty_generics: &syn::TypeGenerics,
1507 where_clause: Option<&syn::WhereClause>,
1508) -> ItemImpl {
1509 syn::parse_quote!(
1510 impl #impl_generics ::autoproto::prost::Message for #ident #ty_generics #where_clause
1511 {
1512 fn encode_raw<__Buffer>(&self, buf: &mut __Buffer)
1513 where
1514 __Buffer: ::autoproto::prost::bytes::BufMut,
1515 {
1516 ::autoproto::generic::protostruct::message_encode_raw(self, buf)
1517 }
1518
1519 fn merge_field<__Buffer: ::autoproto::prost::bytes::Buf>(
1520 &mut self,
1521 tag: u32,
1522 wire_type: ::autoproto::prost::encoding::WireType,
1523 buf: &mut __Buffer,
1524 ctx: ::autoproto::prost::encoding::DecodeContext,
1525 ) -> Result<(), ::autoproto::prost::DecodeError> {
1526 ::autoproto::generic::protostruct::message_merge_field(self, tag, wire_type, buf, ctx)
1527 }
1528
1529 fn encoded_len(&self) -> usize {
1530 ::autoproto::generic::protostruct::message_encoded_len(self)
1531 }
1532
1533 fn clear(&mut self) {
1534 ::autoproto::generic::clear::message_clear(self)
1535 }
1536 }
1537 )
1538}
1539
1540fn impl_proto_for_protostruct(
1541 ident: &Ident,
1542 impl_generics: &syn::ImplGenerics,
1543 ty_generics: &syn::TypeGenerics,
1544 where_clause_builder: &mut WhereClauseBuilder,
1545) -> TokenStream2 {
1546 let protoencode_impl =
1547 impl_protoencode_for_protostruct(ident, impl_generics, ty_generics, where_clause_builder);
1548 let proto_where_clause = where_clause_builder.build().with_self_bound(quote!(
1549 ::autoproto::ProtoStructMut + ::autoproto::ProtoEncode + ::autoproto::Clear
1550 ));
1551
1552 quote!(
1553 impl #impl_generics ::autoproto::Proto for #ident #ty_generics #proto_where_clause
1554 {
1555 fn merge_self(
1556 &mut self,
1557 wire_type: ::autoproto::prost::encoding::WireType,
1558 mut buf: &mut dyn ::autoproto::prost::bytes::Buf,
1559 ctx: ::autoproto::prost::encoding::DecodeContext,
1560 ) -> Result<(), ::autoproto::prost::DecodeError> {
1561 ::autoproto::generic::protostruct::proto_merge_self(self, wire_type, &mut buf, ctx)
1562 }
1563 }
1564
1565 #protoencode_impl
1566 )
1567}
1568
1569fn impl_protoencode_for_protostruct(
1570 ident: &Ident,
1571 impl_generics: &syn::ImplGenerics,
1572 ty_generics: &syn::TypeGenerics,
1573 where_clause_builder: &mut WhereClauseBuilder,
1574) -> ItemImpl {
1575 let where_clause = where_clause_builder.with_self_bound(quote!(::autoproto::ProtoStruct));
1576
1577 syn::parse_quote!(
1578 impl #impl_generics ::autoproto::ProtoEncode for #ident #ty_generics #where_clause
1579 {
1580 fn encode_as_field(&self, tag: ::core::num::NonZeroU32, mut buf: &mut dyn ::autoproto::prost::bytes::BufMut) {
1581 ::autoproto::generic::protostruct::protoencode_encode_as_field(self, tag, buf)
1582 }
1583
1584 fn encoded_len_as_field(&self, tag: ::core::num::NonZeroU32) -> usize {
1585 ::autoproto::generic::protostruct::protoencode_encoded_len_as_field(self, tag)
1586 }
1587 }
1588 )
1589}
1590
1591fn unit_proto_impl(
1592 ident: &Ident,
1593 impl_generics: syn::ImplGenerics,
1594 ty_generics: syn::TypeGenerics,
1595 where_clause: Option<&syn::WhereClause>,
1596) -> TokenStream2 {
1597 quote!(
1598 impl #impl_generics ::autoproto::ProtoEncode for #ident #ty_generics #where_clause {
1599 fn encode_as_field(&self, tag: ::core::num::NonZeroU32, buf: &mut dyn prost::bytes::BufMut) {
1600 <() as ::autoproto::ProtoEncode>::encode_as_field(&(), tag, buf)
1601 }
1602
1603 fn encoded_len_as_field(&self, tag: ::core::num::NonZeroU32) -> usize {
1604 <() as ::autoproto::ProtoEncode>::encoded_len_as_field(&(), tag)
1605 }
1606 }
1607
1608 impl #impl_generics ::autoproto::Proto for #ident #ty_generics #where_clause {
1609 fn merge_self(
1610 &mut self,
1611 wire_type: ::autoproto::prost::encoding::WireType,
1612 buf: &mut dyn ::autoproto::prost::bytes::Buf,
1613 ctx: ::autoproto::prost::encoding::DecodeContext,
1614 ) -> Result<(), ::autoproto::prost::DecodeError> {
1615 <() as ::autoproto::Proto>::merge_self(&mut (), wire_type, buf, ctx)
1616 }
1617 }
1618
1619 impl #impl_generics ::autoproto::prost::Message for #ident #ty_generics #where_clause {
1620 fn encode_raw<__Buffer>(&self, buf: &mut __Buffer)
1621 where
1622 __Buffer: prost::bytes::BufMut,
1623 {
1624 <() as ::autoproto::prost::Message>::encode_raw(&(), buf)
1625 }
1626
1627 fn merge_field<__Buffer: prost::bytes::Buf>(
1628 &mut self,
1629 tag: u32,
1630 wire_type: ::autoproto::prost::encoding::WireType,
1631 buf: &mut __Buffer,
1632 ctx: ::autoproto::prost::encoding::DecodeContext,
1633 ) -> Result<(), ::autoproto::prost::DecodeError> {
1634 <() as ::autoproto::prost::Message>::merge_field(&mut (), tag, wire_type, buf, ctx)
1635 }
1636
1637 fn encoded_len(&self) -> usize {
1638 <() as ::autoproto::prost::Message>::encoded_len(&())
1639 }
1640
1641 fn clear(&mut self) {
1642 <() as ::autoproto::prost::Message>::clear(&mut ())
1643 }
1644 }
1645 )
1646}