protify_proc_macro/
lib.rs1#![allow(
2 clippy::single_match,
3 clippy::collapsible_if,
4 clippy::collapsible_else_if
5)]
6#![cfg_attr(docsrs, feature(doc_cfg))]
7
8use std::{
9 borrow::Cow,
10 fmt::Display,
11 ops::{Deref, Range},
12};
13
14use bool_enum::bool_enum;
15use parsing::*;
16use proc_macro::TokenStream;
17use proc_macro2::{Span, TokenStream as TokenStream2};
18use quote::{ToTokens, format_ident, quote, quote_spanned};
19use syn::{
20 Attribute, Error, Expr, Field, Fields, Ident, ItemEnum, ItemStruct, Lit, LitBool, LitStr, Meta,
21 Path, RangeLimits, Token, Type, Variant, Visibility, bracketed,
22 meta::ParseNestedMeta,
23 parse::{Parse, Parser},
24 parse_macro_input, parse_quote, parse_quote_spanned,
25 spanned::Spanned,
26 token,
27};
28use syn_utils::*;
29
30use crate::{
31 enum_proc_macro::*, extension_macro::*, file_macro::*, impls::*, internals::*,
32 message_proc_macro::*, oneof_proc_macro::*, package_macro::*, service_macro::*,
33};
34
35#[cfg(feature = "cel")]
36mod cel_try_into;
37mod enum_proc_macro;
38mod extension_macro;
39mod file_macro;
40mod impls;
41mod internals;
42mod message_proc_macro;
43mod oneof_proc_macro;
44mod package_macro;
45mod parsing;
46#[cfg(feature = "reflection")]
47mod reflection;
48mod service_macro;
49
50#[doc(hidden)]
51#[proc_macro_derive(__AttrForwarding, attributes(forward))]
52pub fn attr_forwarding_derive_test(_: TokenStream) -> TokenStream {
53 TokenStream::new()
54}
55
56#[cfg(feature = "cel")]
60#[proc_macro_derive(CelOneof, attributes(cel))]
61pub fn cel_oneof_derive(input: TokenStream) -> TokenStream {
62 let item = parse_macro_input!(input as ItemEnum);
63
64 match cel_try_into::derive_cel_value_oneof(&item) {
65 Ok(tokens) => tokens.into(),
66 Err(e) => e.into_compile_error().into(),
67 }
68}
69
70#[cfg(feature = "cel")]
74#[proc_macro_derive(CelValue, attributes(cel))]
75pub fn cel_struct_derive(input: TokenStream) -> TokenStream {
76 let item = parse_macro_input!(input as ItemStruct);
77
78 match cel_try_into::derive_cel_value_struct(&item) {
79 Ok(tokens) => tokens.into(),
80 Err(e) => e.into_compile_error().into(),
81 }
82}
83
84#[cfg(feature = "reflection")]
88#[proc_macro_derive(ValidatedOneof, attributes(proto))]
89pub fn validated_oneof_derive(input: TokenStream) -> TokenStream {
90 let mut item = parse_macro_input!(input as ItemEnum);
91
92 reflection::reflection_oneof_derive(&mut item).into()
93}
94
95#[cfg(feature = "reflection")]
99#[proc_macro_derive(ProtoEnum, attributes(proto))]
100pub fn enum_derive(input: TokenStream) -> TokenStream {
101 let item = parse_macro_input!(input as ItemEnum);
102
103 reflection::enum_reflection_derive(&item).into()
104}
105
106#[cfg(feature = "reflection")]
110#[proc_macro_derive(ValidatedMessage, attributes(proto))]
111pub fn validated_message_derive(input: TokenStream) -> TokenStream {
112 let mut item = parse_macro_input!(input as ItemStruct);
113
114 reflection::reflection_message_derive(&mut item).into()
115}
116
117#[doc(hidden)]
118#[proc_macro]
119pub fn impl_known_type(input: TokenStream) -> TokenStream {
120 match well_known_type_impl_macro(input.into()) {
121 Ok(output) => output.into(),
122 Err(e) => e.into_compile_error().into(),
123 }
124}
125
126#[doc(hidden)]
127#[proc_macro]
128pub fn builder_state_macro(input: TokenStream) -> TokenStream {
129 match builder_macro(input.into()) {
130 Ok(output) => output.into(),
131 Err(e) => e.into_compile_error().into(),
132 }
133}
134
135#[doc = include_str!("../docs/file_macro.md")]
136#[proc_macro]
137pub fn define_proto_file(input: TokenStream) -> TokenStream {
138 match process_file_macro(input.into()) {
139 Ok(output) => output.into(),
140 Err(e) => e.into_compile_error().into(),
141 }
142}
143
144#[allow(clippy::doc_overindented_list_items)]
145#[proc_macro]
183pub fn proto_package(input: TokenStream) -> TokenStream {
184 match package_macro_impl(input.into()) {
185 Ok(output) => output.into(),
186 Err(e) => e.into_compile_error().into(),
187 }
188}
189
190#[doc = include_str!("../docs/message_macro.md")]
191#[doc = include_str!("../docs/field_ref.md")]
194#[proc_macro_attribute]
195pub fn proto_message(args: TokenStream, input: TokenStream) -> TokenStream {
196 let item = parse_macro_input!(input as ItemStruct);
197
198 message_proc_macro(item, args.into()).into()
199}
200
201#[doc(hidden)]
202#[proc_macro_derive(__Message, attributes(proto))]
203pub fn message_derive(_input: TokenStream) -> TokenStream {
204 TokenStream::new()
205}
206
207#[doc = include_str!("../docs/extension_macro.md")]
208#[proc_macro_attribute]
209pub fn proto_extension(args: TokenStream, input: TokenStream) -> TokenStream {
210 let mut item = parse_macro_input!(input as ItemStruct);
211
212 let extra_tokens = match process_extension_derive(args.into(), &mut item) {
213 Ok(output) => output,
214 Err(e) => e.to_compile_error(),
215 };
216
217 quote! {
218 #[derive(::protify::macros::__Extension)]
219 #item
220
221 #extra_tokens
222 }
223 .into()
224}
225
226#[doc(hidden)]
227#[proc_macro_derive(__Extension, attributes(proto))]
228pub fn extension_derive(_input: TokenStream) -> TokenStream {
229 TokenStream::new()
230}
231
232#[doc = include_str!("../docs/service_macro.md")]
233#[proc_macro_attribute]
234pub fn proto_service(_args: TokenStream, input: TokenStream) -> TokenStream {
235 let item = parse_macro_input!(input as ItemEnum);
236
237 let output = match process_service_derive(&item) {
238 Ok(output) => output,
239 Err(e) => return e.to_compile_error().into(),
240 };
241
242 output.into()
243}
244
245#[doc(hidden)]
246#[proc_macro_derive(__Service, attributes(proto))]
247pub fn service_derive(_input: TokenStream) -> TokenStream {
248 TokenStream::new()
249}
250
251#[doc = include_str!("../docs/enum_macro.md")]
252#[proc_macro_attribute]
253pub fn proto_enum(_args: TokenStream, input: TokenStream) -> TokenStream {
254 let item = parse_macro_input!(input as ItemEnum);
255
256 enum_proc_macro(item).into()
257}
258
259#[doc(hidden)]
260#[proc_macro_derive(__Enum, attributes(proto))]
261pub fn enum_empty_derive(_input: TokenStream) -> TokenStream {
262 TokenStream::new()
263}
264
265#[doc = include_str!("../docs/oneof_macro.md")]
266#[doc = include_str!("../docs/field_ref.md")]
269#[proc_macro_attribute]
270pub fn proto_oneof(args: TokenStream, input: TokenStream) -> TokenStream {
271 let item = parse_macro_input!(input as ItemEnum);
272
273 process_oneof_proc_macro(item, args.into()).into()
274}
275
276#[doc(hidden)]
277#[proc_macro_derive(__Oneof, attributes(proto))]
278pub fn oneof_derive(_input: TokenStream) -> TokenStream {
279 TokenStream::new()
280}