Skip to main content

sqlparser_derive/
visit.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Implementation of the `Visit` and `VisitMut` derive macros.
19
20use proc_macro2::TokenStream;
21use quote::{format_ident, quote, quote_spanned, ToTokens};
22use syn::spanned::Spanned;
23use syn::{
24    parse::{Parse, ParseStream},
25    parse_quote, Attribute, Data, Fields, GenericParam, Generics, Ident, Index, LitStr, Meta,
26    Token, Type, TypePath,
27};
28use syn::{Path, PathArguments};
29
30pub(crate) struct VisitType {
31    pub visit_trait: TokenStream,
32    pub visitor_trait: TokenStream,
33    pub modifier: Option<TokenStream>,
34}
35
36pub(crate) fn derive_visit(
37    input: syn::DeriveInput,
38    visit_type: &VisitType,
39) -> proc_macro::TokenStream {
40    let name = input.ident;
41
42    let VisitType {
43        visit_trait,
44        visitor_trait,
45        modifier,
46    } = visit_type;
47
48    let attributes = Attributes::parse(&input.attrs);
49    // Add a bound `T: Visit` to every type parameter T.
50    let generics = add_trait_bounds(input.generics, visit_type);
51    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
52
53    let (pre_visit, post_visit) = attributes.visit({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    _s
}quote!(self));
54    let children = visit_children(&input.data, visit_type);
55
56    let expanded = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_ident(&mut _s, "sqlparser");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ast");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "cfg_attr");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "feature");
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::parse(&mut _s,
                                "\"recursive-protection\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "recursive");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "recursive");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "visit");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "V");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sqlparser");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ast");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::ToTokens::to_tokens(&visitor_trait, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::ToTokens::to_tokens(&modifier, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "visitor");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "V");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ops");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ControlFlow");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "V");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Break");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
                    ::quote::ToTokens::to_tokens(&children, &mut _s);
                    ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ops");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ControlFlow");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Continue");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
57        // The generated impl.
58        // Note that it uses [`recursive::recursive`] to protect from stack overflow.
59        // See tests in https://github.com/apache/datafusion-sqlparser-rs/pull/1522/ for more info.
60        impl #impl_generics sqlparser::ast::#visit_trait for #name #ty_generics #where_clause {
61             #[cfg_attr(feature = "recursive-protection", recursive::recursive)]
62            fn visit<V: sqlparser::ast::#visitor_trait>(
63                &#modifier self,
64                visitor: &mut V
65            ) -> ::std::ops::ControlFlow<V::Break> {
66                #pre_visit
67                #children
68                #post_visit
69                ::std::ops::ControlFlow::Continue(())
70            }
71        }
72    };
73
74    proc_macro::TokenStream::from(expanded)
75}
76
77/// Parses attributes that can be provided to this macro
78///
79/// `#[visit(leaf, with = "visit_expr")]`
80#[derive(#[automatically_derived]
impl ::core::default::Default for Attributes {
    #[inline]
    fn default() -> Attributes {
        Attributes { with: ::core::default::Default::default() }
    }
}Default)]
81struct Attributes {
82    /// Content for the `with` attribute
83    with: Option<Ident>,
84}
85
86struct WithIdent {
87    with: Option<Ident>,
88}
89impl Parse for WithIdent {
90    fn parse(input: ParseStream) -> Result<Self, syn::Error> {
91        let mut result = WithIdent { with: None };
92        let ident = input.parse::<Ident>()?;
93        if ident != "with" {
94            return Err(syn::Error::new(
95                ident.span(),
96                "Expected identifier to be `with`",
97            ));
98        }
99        input.parse::<::syn::token::EqToken!(=)>()?;
100        let s = input.parse::<LitStr>()?;
101        result.with = Some(match ::quote::__private::IdentFragmentAdapter(&s.value()) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}", arg))
                    }),
            ::quote::__private::Option::Some::<::quote::__private::Span>(s.span())),
}format_ident!("{}", s.value(), span = s.span()));
102        Ok(result)
103    }
104}
105
106impl Attributes {
107    fn parse(attrs: &[Attribute]) -> Self {
108        let mut out = Self::default();
109        for attr in attrs {
110            if let Meta::List(ref metalist) = attr.meta {
111                if metalist.path.is_ident("visit") {
112                    match syn::parse2::<WithIdent>(metalist.tokens.clone()) {
113                        Ok(with_ident) => {
114                            out.with = with_ident.with;
115                        }
116                        Err(e) => {
117                            { ::core::panicking::panic_display(&e); };panic!("{}", e);
118                        }
119                    }
120                }
121            }
122        }
123        out
124    }
125
126    /// Returns the pre and post visit token streams
127    fn visit(&self, s: TokenStream) -> (Option<TokenStream>, Option<TokenStream>) {
128        let pre_visit = self.with.as_ref().map(|m| {
129            let m = match ::quote::__private::IdentFragmentAdapter(&m) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("pre_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("pre_{}", m);
130            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "visitor");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&m, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&s, &mut _s);
            _s
        });
    ::quote::__private::push_question(&mut _s);
    ::quote::__private::push_semi(&mut _s);
    _s
}quote!(visitor.#m(#s)?;)
131        });
132        let post_visit = self.with.as_ref().map(|m| {
133            let m = match ::quote::__private::IdentFragmentAdapter(&m) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("post_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("post_{}", m);
134            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "visitor");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&m, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&s, &mut _s);
            _s
        });
    ::quote::__private::push_question(&mut _s);
    ::quote::__private::push_semi(&mut _s);
    _s
}quote!(visitor.#m(#s)?;)
135        });
136        (pre_visit, post_visit)
137    }
138}
139
140// Add a bound `T: Visit` to every type parameter T.
141fn add_trait_bounds(mut generics: Generics, VisitType { visit_trait, .. }: &VisitType) -> Generics {
142    for param in &mut generics.params {
143        if let GenericParam::Type(ref mut type_param) = *param {
144            type_param
145                .bounds
146                .push(::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "sqlparser");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "ast");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
        _s
    })parse_quote!(sqlparser::ast::#visit_trait));
147        }
148    }
149    generics
150}
151
152// Generate the body of the visit implementation for the given type
153fn visit_children(
154    data: &Data,
155    VisitType {
156        visit_trait,
157        modifier,
158        ..
159    }: &VisitType,
160) -> TokenStream {
161    match data {
162        Data::Struct(data) => match &data.fields {
163            Fields::Named(fields) => {
164                let recurse = fields.named.iter().map(|f| {
165                    let name = &f.ident;
166                    let is_option = is_option(&f.ty);
167                    let attributes = Attributes::parse(&f.attrs);
168                    if is_option && attributes.with.is_some() {
169                        let (pre_visit, post_visit) = attributes.visit({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "value");
    _s
}quote!(value));
170                        {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(f.span()).__into_span();
    ::quote::__private::push_ident_spanned(&mut _s, _span, "if");
    ::quote::__private::push_ident_spanned(&mut _s, _span, "let");
    ::quote::__private::push_ident_spanned(&mut _s, _span, "Some");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_ident_spanned(&mut _s, _span, "value");
            _s
        });
    ::quote::__private::push_eq_spanned(&mut _s, _span);
    ::quote::__private::push_and_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&modifier, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "self");
    ::quote::__private::push_dot_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
            ::quote::__private::push_ident_spanned(&mut _s, _span,
                "sqlparser");
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "ast");
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "visit");
            ::quote::__private::push_group_spanned(&mut _s, _span,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    let _span: ::quote::__private::Span =
                        ::quote::__private::get_span(_span).__into_span();
                    ::quote::__private::push_ident_spanned(&mut _s, _span,
                        "value");
                    ::quote::__private::push_comma_spanned(&mut _s, _span);
                    ::quote::__private::push_ident_spanned(&mut _s, _span,
                        "visitor");
                    _s
                });
            ::quote::__private::push_question_spanned(&mut _s, _span);
            ::quote::__private::push_semi_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
            _s
        });
    _s
}quote_spanned!(f.span() =>
171                            if let Some(value) = &#modifier self.#name {
172                                #pre_visit sqlparser::ast::#visit_trait::visit(value, visitor)?; #post_visit
173                            }
174                        )
175                    } else {
176                        let (pre_visit, post_visit) = attributes.visit({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_and(&mut _s);
    ::quote::ToTokens::to_tokens(&modifier, &mut _s);
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote!(&#modifier self.#name));
177                        {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(f.span()).__into_span();
    ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "sqlparser");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "ast");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "visit");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_and_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&modifier, &mut _s);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "self");
            ::quote::__private::push_dot_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_comma_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "visitor");
            _s
        });
    ::quote::__private::push_question_spanned(&mut _s, _span);
    ::quote::__private::push_semi_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
    _s
}quote_spanned!(f.span() =>
178                            #pre_visit sqlparser::ast::#visit_trait::visit(&#modifier self.#name, visitor)?; #post_visit
179                        )
180                    }
181                });
182                {
    let mut _s = ::quote::__private::TokenStream::new();
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut recurse, i) = recurse.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let recurse =
                match recurse.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&recurse, &mut _s);
        }
    }
    _s
}quote! {
183                    #(#recurse)*
184                }
185            }
186            Fields::Unnamed(fields) => {
187                let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
188                    let index = Index::from(i);
189                    let attributes = Attributes::parse(&f.attrs);
190                    let (pre_visit, post_visit) = attributes.visit({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_and(&mut _s);
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&index, &mut _s);
    _s
}quote!(&self.#index));
191                    {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(f.span()).__into_span();
    ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "sqlparser");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "ast");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "visit");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_and_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&modifier, &mut _s);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "self");
            ::quote::__private::push_dot_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&index, &mut _s);
            ::quote::__private::push_comma_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "visitor");
            _s
        });
    ::quote::__private::push_question_spanned(&mut _s, _span);
    ::quote::__private::push_semi_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
    _s
}quote_spanned!(f.span() => #pre_visit sqlparser::ast::#visit_trait::visit(&#modifier self.#index, visitor)?; #post_visit)
192                });
193                {
    let mut _s = ::quote::__private::TokenStream::new();
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut recurse, i) = recurse.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let recurse =
                match recurse.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&recurse, &mut _s);
        }
    }
    _s
}quote! {
194                    #(#recurse)*
195                }
196            }
197            Fields::Unit => {
198                ::quote::__private::TokenStream::new()quote!()
199            }
200        },
201        Data::Enum(data) => {
202            let statements = data.variants.iter().map(|v| {
203                let name = &v.ident;
204                match &v.fields {
205                    Fields::Named(fields) => {
206                        let names = fields.named.iter().map(|f| &f.ident);
207                        let visit = fields.named.iter().map(|f| {
208                            let name = &f.ident;
209                            let attributes = Attributes::parse(&f.attrs);
210                            let (pre_visit, post_visit) = attributes.visit(name.to_token_stream());
211                            {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(f.span()).__into_span();
    ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "sqlparser");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "ast");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "visit");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_comma_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "visitor");
            _s
        });
    ::quote::__private::push_question_spanned(&mut _s, _span);
    ::quote::__private::push_semi_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
    _s
}quote_spanned!(f.span() => #pre_visit sqlparser::ast::#visit_trait::visit(#name, visitor)?; #post_visit)
212                        });
213
214                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut names, i) = names.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let names =
                        match names.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&names, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_fat_arrow(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut visit, i) = visit.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let visit =
                        match visit.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&visit, &mut _s);
                }
            }
            _s
        });
    _s
}quote!(
215                            Self::#name { #(#names),* } => {
216                                #(#visit)*
217                            }
218                        )
219                    }
220                    Fields::Unnamed(fields) => {
221                        let names = fields.unnamed.iter().enumerate().map(|(i, f)| match ::quote::__private::IdentFragmentAdapter(&i) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("_{0}", arg))
                    }),
            ::quote::__private::Option::Some::<::quote::__private::Span>(f.span())),
}format_ident!("_{}", i, span = f.span()));
222                        let visit = fields.unnamed.iter().enumerate().map(|(i, f)| {
223                            let name = match ::quote::__private::IdentFragmentAdapter(&i) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("_{}", i);
224                            let attributes = Attributes::parse(&f.attrs);
225                            let (pre_visit, post_visit) = attributes.visit(name.to_token_stream());
226                            {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(f.span()).__into_span();
    ::quote::ToTokens::to_tokens(&pre_visit, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "sqlparser");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "ast");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&visit_trait, &mut _s);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "visit");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_comma_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "visitor");
            _s
        });
    ::quote::__private::push_question_spanned(&mut _s, _span);
    ::quote::__private::push_semi_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&post_visit, &mut _s);
    _s
}quote_spanned!(f.span() => #pre_visit sqlparser::ast::#visit_trait::visit(#name, visitor)?; #post_visit)
227                        });
228
229                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut names, i) = names.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let names =
                        match names.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&names, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_fat_arrow(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut visit, i) = visit.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let visit =
                        match visit.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&visit, &mut _s);
                }
            }
            _s
        });
    _s
}quote! {
230                            Self::#name ( #(#names),*) => {
231                                #(#visit)*
232                            }
233                        }
234                    }
235                    Fields::Unit => {
236                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_fat_arrow(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
237                            Self::#name => {}
238                        }
239                    }
240                }
241            });
242
243            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "match");
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut statements, i) = statements.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let statements =
                        match statements.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&statements, &mut _s);
                }
            }
            _s
        });
    _s
}quote! {
244                match self {
245                    #(#statements),*
246                }
247            }
248        }
249        Data::Union(_) => ::core::panicking::panic("not implemented")unimplemented!(),
250    }
251}
252
253fn is_option(ty: &Type) -> bool {
254    if let Type::Path(TypePath {
255        path: Path { segments, .. },
256        ..
257    }) = ty
258    {
259        if let Some(segment) = segments.last() {
260            if segment.ident == "Option" {
261                if let PathArguments::AngleBracketed(args) = &segment.arguments {
262                    return args.args.len() == 1;
263                }
264            }
265        }
266    }
267    false
268}