use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, quote_spanned};
use syn::{
    parse::{Parse, ParseBuffer, ParseStream},
    visit_mut::VisitMut,
    *,
};

use super::PIN;
use crate::utils::{
    determine_lifetime_name, determine_visibility, insert_lifetime_and_bound, Immutable, Mutable,
    Owned, ParseBufferExt, ReplaceReceiver, SliceExt, Variants,
};

pub(super) fn parse_derive(input: TokenStream) -> Result<TokenStream> {
    let mut input = syn::parse2(input)?;
    let DeriveInput { attrs, vis, ident, generics, data } = &mut input;
    let mut cx = Context::new(attrs, vis, ident, generics)?;
    let packed_check;

    let (mut items, scoped_items) = match data {
        Data::Struct(data) => {
            // Do this first for a better error message.
            packed_check = Some(cx.ensure_not_packed(&data.fields)?);
            cx.parse_struct(data)?
        }
        Data::Enum(data) => {
            // We don't need to check for `#[repr(packed)]`,
            // since it does not apply to enums.
            packed_check = None;
            cx.parse_enum(data)?
        }
        Data::Union(_) => {
            return Err(error!(
                input,
                "#[pin_project] attribute may only be used on structs or enums"
            ));
        }
    };

    let unpin_impl = cx.make_unpin_impl();
    let drop_impl = cx.make_drop_impl();
    let dummy_const = format_ident!("__SCOPE_{}", ident);
    items.extend(quote! {
        // All items except projected types are generated inside a `const` scope.
        // This makes it impossible for user code to refer to these types.
        // However, this prevents Rustdoc from displaying docs for any
        // of our types. In particular, users cannot see the
        // automatically generated `Unpin` impl for the '__UnpinStruct' types
        //
        // Previously, we provided a flag to correctly document the
        // automatically generated `Unpin` impl by using def-site hygiene,
        // but it is now removed.
        //
        // Refs:
        // * https://github.com/rust-lang/rust/issues/63281
        // * https://github.com/taiki-e/pin-project/pull/53#issuecomment-525906867
        // * https://github.com/taiki-e/pin-project/pull/70
        #[doc(hidden)]
        #[allow(non_upper_case_globals)]
        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
        const #dummy_const: () = {
            #scoped_items
            #unpin_impl
            #drop_impl
            #packed_check
        };
    });
    Ok(items)
}

fn validate_struct(ident: &Ident, fields: &Fields) -> Result<()> {
    if fields.is_empty() {
        let msg = "#[pin_project] attribute may not be used on structs with zero fields";
        if let Fields::Unit = fields { Err(error!(ident, msg)) } else { Err(error!(fields, msg)) }
    } else {
        Ok(())
    }
}

fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> {
    if variants.is_empty() {
        return Err(Error::new(
            brace_token.span,
            "#[pin_project] attribute may not be used on enums without variants",
        ));
    }
    let has_field = variants.iter().try_fold(false, |has_field, v| {
        if let Some((_, e)) = &v.discriminant {
            Err(error!(e, "#[pin_project] attribute may not be used on enums with discriminants"))
        } else if let Some(attr) = v.attrs.find(PIN) {
            Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants"))
        } else if v.fields.is_empty() {
            Ok(has_field)
        } else {
            Ok(true)
        }
    })?;
    if has_field {
        Ok(())
    } else {
        Err(error!(variants, "#[pin_project] attribute may not be used on enums with zero fields"))
    }
}

struct Args {
    /// `PinnedDrop` argument.
    pinned_drop: Option<Span>,
    /// `Replace` argument.
    replace: Option<Span>,
    /// `UnsafeUnpin` or `!Unpin` argument.
    unpin_impl: UnpinImpl,
    /// `project = <ident>`.
    project: Option<Ident>,
    /// `project_ref = <ident>`.
    project_ref: Option<Ident>,
    /// `project_replace = <ident>`.
    project_replace: Option<Ident>,
}

const DUPLICATE_PIN: &str = "duplicate #[pin] attribute";

impl Args {
    fn get(attrs: &[Attribute]) -> Result<Self> {
        let mut prev: Option<(&Attribute, Result<Self>)> = None;

        for attr in attrs.iter().filter(|attr| attr.path.is_ident(PIN)) {
            if let Some((prev_attr, prev_res)) = &prev {
                // As the `#[pin]` attribute generated by `#[pin_project]`
                // has the same span as `#[pin_project]`, it is possible
                // that a useless error message will be generated.
                let res = syn::parse2::<Self>(attr.tokens.clone());
                let span = match (&prev_res, res) {
                    (Ok(_), Ok(_)) => unreachable!(),
                    (_, Ok(_)) => prev_attr,
                    (Ok(_), _) => attr,
                    (Err(prev_err), Err(_)) => {
                        if prev_err.to_string() == DUPLICATE_PIN {
                            attr
                        } else {
                            prev_attr
                        }
                    }
                };
                // This error message is not ideal, but as this should basically be
                // rejected by attribute side, users will rarely actually see this error.
                return Err(error!(span, DUPLICATE_PIN));
            }
            prev = Some((attr, syn::parse2::<Self>(attr.tokens.clone())));
        }

        // This `unwrap` only fails if another macro removes `#[pin]`.
        prev.unwrap().1
    }
}

impl Parse for Args {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        mod kw {
            syn::custom_keyword!(Unpin);
        }

        // `(__private(<args>))` -> `<args>`
        fn parse_input(input: ParseStream<'_>) -> Result<ParseBuffer<'_>> {
            if let Ok(content) = input.parenthesized() {
                if let Ok(private) = content.parse::<Ident>() {
                    if private == "__private" {
                        if let Ok(args) = content.parenthesized() {
                            return Ok(args);
                        }
                    }
                }
            }

            // If this fails, it means that there is a `#[pin]` attribute
            // inserted by something other than `#[pin_project]` attribute.
            // This error message is not ideal, but as this should basically be
            // rejected by attribute side, users will rarely actually see this error.
            Err(error!(TokenStream::new(), DUPLICATE_PIN))
        }

        // Replace `prev` with `new`. Returns `Err` if `prev` is `Some`.
        fn update<T>(prev: &mut Option<T>, new: T, token: &Ident) -> Result<()> {
            if prev.replace(new).is_some() {
                Err(error!(token, "duplicate `{}` argument", token))
            } else {
                Ok(())
            }
        }

        let input = parse_input(input)?;
        let mut pinned_drop = None;
        let mut replace = None;
        let mut unsafe_unpin = None;
        let mut not_unpin = None;
        let mut project = None;
        let mut project_ref = None;
        let mut project_replace: Option<(Span, Ident)> = None;
        while !input.is_empty() {
            if input.peek(token::Bang) {
                let t: token::Bang = input.parse()?;
                let k: kw::Unpin = input.parse()?;
                if not_unpin.replace(k).is_some() {
                    let span = quote!(#t #k);
                    return Err(error!(span, "duplicate `!Unpin` argument",));
                }
            } else {
                let token = input.parse::<Ident>()?;
                match &*token.to_string() {
                    "PinnedDrop" => update(&mut pinned_drop, token.span(), &token)?,
                    "Replace" => update(&mut replace, token.span(), &token)?,
                    "UnsafeUnpin" => update(&mut unsafe_unpin, token.span(), &token)?,
                    "project" => {
                        let _: token::Eq = input.parse()?;
                        update(&mut project, input.parse()?, &token)?;
                    }
                    "project_ref" => {
                        let _: token::Eq = input.parse()?;
                        update(&mut project_ref, input.parse()?, &token)?;
                    }
                    "project_replace" => {
                        let _: token::Eq = input.parse()?;
                        update(&mut project_replace, (token.span(), input.parse()?), &token)?;
                    }
                    _ => return Err(error!(token, "unexpected argument: {}", token)),
                }
            }

            if !input.is_empty() {
                let _: token::Comma = input.parse()?;
            }
        }

        if let (Some(span), Some(_)) = (pinned_drop, replace) {
            return Err(Error::new(
                span,
                "arguments `PinnedDrop` and `Replace` are mutually exclusive",
            ));
        }
        let unpin_impl = match (unsafe_unpin, not_unpin) {
            (Some(span), Some(_)) => {
                return Err(Error::new(
                    span,
                    "arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive",
                ));
            }
            (None, None) => UnpinImpl::Default,
            (Some(span), None) => UnpinImpl::Unsafe(span),
            (None, Some(span)) => UnpinImpl::Negative(span.span),
        };

        if let (Some((span, _)), None) = (&project_replace, replace) {
            Err(Error::new(
                *span,
                "`project_replace` argument can only be used together with `Replace` argument",
            ))
        } else {
            Ok(Self {
                pinned_drop,
                replace,
                unpin_impl,
                project,
                project_ref,
                project_replace: project_replace.map(|(_, i)| i),
            })
        }
    }
}

struct OriginalType<'a> {
    /// Attributes of the original type.
    attrs: &'a [Attribute],
    /// Visibility of the original type.
    vis: &'a Visibility,
    /// Name of the original type.
    ident: &'a Ident,
    /// Generics of the original type.
    generics: &'a Generics,
}

struct ProjectedType {
    /// Visibility of the projected types.
    vis: Visibility,
    /// Name of the projected type returned by `project` method.
    mut_ident: Ident,
    /// Name of the projected type returned by `project_ref` method.
    ref_ident: Ident,
    /// Name of the projected type returned by `project_replace` method.
    own_ident: Ident,
    /// Lifetime on the generated projected types.
    lifetime: Lifetime,
    /// Generics of the projected types.
    generics: Generics,
    /// `where` clause of the projected types. This has an additional
    /// bound generated by `insert_lifetime_and_bound`
    where_clause: WhereClause,
}

struct ProjectedVariants {
    proj_variants: TokenStream,
    proj_ref_variants: TokenStream,
    proj_own_variants: TokenStream,
    proj_arms: TokenStream,
    proj_ref_arms: TokenStream,
    proj_own_arms: TokenStream,
}

#[derive(Default)]
struct ProjectedFields {
    proj_pat: TokenStream,
    proj_body: TokenStream,
    proj_fields: TokenStream,
    proj_ref_fields: TokenStream,
    proj_own_fields: TokenStream,
    proj_move: TokenStream,
    proj_drop: Vec<Ident>,
}

struct Context<'a> {
    /// The original type.
    orig: OriginalType<'a>,
    /// The projected types.
    proj: ProjectedType,
    /// Types of the pinned fields.
    pinned_fields: Vec<Type>,
    /// `PinnedDrop` argument.
    pinned_drop: Option<Span>,
    /// `Replace` argument (requires Sized bound)
    replace: Option<Span>,
    /// `UnsafeUnpin` or `!Unpin` argument.
    unpin_impl: UnpinImpl,
    /// `project` argument.
    project: bool,
    /// `project_ref` argument.
    project_ref: bool,
    /// `project_replace` argument.
    project_replace: bool,
}

#[derive(Clone, Copy)]
enum UnpinImpl {
    Default,
    /// `UnsafeUnpin`.
    Unsafe(Span),
    /// `!Unpin`.
    Negative(Span),
}

impl<'a> Context<'a> {
    fn new(
        attrs: &'a [Attribute],
        vis: &'a Visibility,
        ident: &'a Ident,
        generics: &'a mut Generics,
    ) -> Result<Self> {
        let Args { pinned_drop, unpin_impl, replace, project, project_ref, project_replace } =
            Args::get(attrs)?;

        let ty_generics = generics.split_for_impl().1;
        let self_ty = syn::parse_quote!(#ident #ty_generics);
        let mut visitor = ReplaceReceiver(&self_ty);
        visitor.visit_where_clause_mut(generics.make_where_clause());

        let mut lifetime_name = String::from("'pin");
        determine_lifetime_name(&mut lifetime_name, generics);
        let lifetime = Lifetime::new(&lifetime_name, Span::call_site());

        let mut proj_generics = generics.clone();
        let ty_generics = generics.split_for_impl().1;
        let ty_generics_as_generics = syn::parse_quote!(#ty_generics);
        let pred = insert_lifetime_and_bound(
            &mut proj_generics,
            lifetime.clone(),
            &ty_generics_as_generics,
            ident,
        );
        let mut where_clause = generics.clone().make_where_clause().clone();
        where_clause.predicates.push(pred);

        Ok(Self {
            pinned_drop,
            replace,
            unpin_impl,
            project: project.is_some(),
            project_ref: project_ref.is_some(),
            project_replace: project_replace.is_some(),
            proj: ProjectedType {
                vis: determine_visibility(vis),
                mut_ident: project.unwrap_or_else(|| Mutable.proj_ident(ident)),
                ref_ident: project_ref.unwrap_or_else(|| Immutable.proj_ident(ident)),
                own_ident: project_replace.unwrap_or_else(|| Owned.proj_ident(ident)),
                lifetime,
                generics: proj_generics,
                where_clause,
            },
            orig: OriginalType { attrs, vis, ident, generics },
            pinned_fields: Vec::new(),
        })
    }

    fn parse_struct(
        &mut self,
        DataStruct { fields, .. }: &DataStruct,
    ) -> Result<(TokenStream, TokenStream)> {
        validate_struct(self.orig.ident, fields)?;

        let ProjectedFields {
            proj_pat,
            proj_body,
            proj_fields,
            proj_ref_fields,
            proj_own_fields,
            proj_move,
            proj_drop,
        } = match fields {
            Fields::Named(fields) => self.visit_named(fields)?,
            Fields::Unnamed(fields) => self.visit_unnamed(fields)?,
            Fields::Unit => unreachable!(),
        };

        let proj_ident = &self.proj.mut_ident;
        let proj_ref_ident = &self.proj.ref_ident;
        let proj_own_ident = &self.proj.own_ident;
        let vis = &self.proj.vis;
        let mut orig_generics = self.orig.generics.clone();
        let orig_where_clause = orig_generics.where_clause.take();
        let proj_generics = &self.proj.generics;
        let where_clause = &self.proj.where_clause;

        // For tuple structs, we need to generate `(T1, T2) where Foo: Bar`
        // For non-tuple structs, we need to generate `where Foo: Bar { field1: T }`
        let (where_clause_fields, where_clause_ref_fields, where_clause_own_fields) = match fields {
            Fields::Named(_) => (
                quote!(#where_clause #proj_fields),
                quote!(#where_clause #proj_ref_fields),
                quote!(#orig_where_clause #proj_own_fields),
            ),
            Fields::Unnamed(_) => (
                quote!(#proj_fields #where_clause;),
                quote!(#proj_ref_fields #where_clause;),
                quote!(#proj_own_fields #orig_where_clause;),
            ),
            Fields::Unit => unreachable!(),
        };

        // If the user gave it a name, it should appear in the document.
        let doc_attr = quote!(#[doc(hidden)]);
        let doc_proj = if self.project { None } else { Some(&doc_attr) };
        let doc_proj_ref = if self.project_ref { None } else { Some(&doc_attr) };
        let doc_proj_own = if self.project_replace { None } else { Some(&doc_attr) };
        let mut proj_items = quote! {
            #doc_proj
            #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
            #[allow(dead_code)] // This lint warns unused fields/variants.
            #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
            #vis struct #proj_ident #proj_generics #where_clause_fields
            #doc_proj_ref
            #[allow(dead_code)] // This lint warns unused fields/variants.
            #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
            #vis struct #proj_ref_ident #proj_generics #where_clause_ref_fields
        };
        if self.replace.is_some() {
            // Currently, using quote_spanned here does not seem to have any effect on the diagnostics.
            proj_items.extend(quote! {
                #doc_proj_own
                #[allow(dead_code)] // This lint warns unused fields/variants.
                #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
                #vis struct #proj_own_ident #orig_generics #where_clause_own_fields
            });
        }

        let proj_mut_body = quote! {
            let Self #proj_pat = self.get_unchecked_mut();
            #proj_ident #proj_body
        };
        let proj_ref_body = quote! {
            let Self #proj_pat = self.get_ref();
            #proj_ref_ident #proj_body
        };
        let proj_own_body = quote! {
            let __self_ptr: *mut Self = self.get_unchecked_mut();
            let Self #proj_pat = &mut *__self_ptr;

            // First, extract all the unpinned fields
            let __result = #proj_own_ident #proj_move;

            // Destructors will run in reverse order, so next create a guard to overwrite
            // `self` with the replacement value without calling destructors.
            let __guard = ::pin_project::__private::UnsafeOverwriteGuard {
                target: __self_ptr,
                value: ::pin_project::__reexport::mem::ManuallyDrop::new(__replacement),
            };

            // Now create guards to drop all the pinned fields
            //
            // Due to a compiler bug (https://github.com/rust-lang/rust/issues/47949)
            // this must be in its own scope, or else `__result` will not be dropped
            // if any of the destructors panic.
            {
                #( let __guard = ::pin_project::__private::UnsafeDropInPlaceGuard(#proj_drop); )*
            }

            // Finally, return the result
            __result
        };
        let proj_impl = self.make_proj_impl(&proj_mut_body, &proj_ref_body, &proj_own_body);

        Ok((proj_items, proj_impl))
    }

    fn parse_enum(
        &mut self,
        DataEnum { brace_token, variants, .. }: &DataEnum,
    ) -> Result<(TokenStream, TokenStream)> {
        validate_enum(*brace_token, variants)?;

        let ProjectedVariants {
            proj_variants,
            proj_ref_variants,
            proj_own_variants,
            proj_arms,
            proj_ref_arms,
            proj_own_arms,
        } = self.visit_variants(variants)?;

        let proj_ident = &self.proj.mut_ident;
        let proj_ref_ident = &self.proj.ref_ident;
        let proj_own_ident = &self.proj.own_ident;
        let vis = &self.proj.vis;
        let mut orig_generics = self.orig.generics.clone();
        let orig_where_clause = orig_generics.where_clause.take();
        let proj_generics = &self.proj.generics;
        let where_clause = &self.proj.where_clause;

        // If the user gave it a name, it should appear in the document.
        let doc_attr = quote!(#[doc(hidden)]);
        let doc_proj = if self.project { None } else { Some(&doc_attr) };
        let doc_proj_ref = if self.project_ref { None } else { Some(&doc_attr) };
        let doc_proj_own = if self.project_replace { None } else { Some(&doc_attr) };
        let mut proj_items = quote! {
            #doc_proj
            #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
            #[allow(dead_code)] // This lint warns unused fields/variants.
            #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
            #vis enum #proj_ident #proj_generics #where_clause {
                #proj_variants
            }
            #doc_proj_ref
            #[allow(dead_code)] // This lint warns unused fields/variants.
            #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
            #vis enum #proj_ref_ident #proj_generics #where_clause {
                #proj_ref_variants
            }
        };
        if self.replace.is_some() {
            // Currently, using quote_spanned here does not seem to have any effect on the diagnostics.
            proj_items.extend(quote! {
                #doc_proj_own
                #[allow(dead_code)] // This lint warns unused fields/variants.
                #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
                #vis enum #proj_own_ident #orig_generics #orig_where_clause {
                    #proj_own_variants
                }
            });
        }

        let proj_mut_body = quote! {
            match self.get_unchecked_mut() {
                #proj_arms
            }
        };
        let proj_ref_body = quote! {
            match self.get_ref() {
                #proj_ref_arms
            }
        };
        let proj_own_body = quote! {
            let __self_ptr: *mut Self = self.get_unchecked_mut();
            match &mut *__self_ptr {
                #proj_own_arms
            }
        };
        let proj_impl = self.make_proj_impl(&proj_mut_body, &proj_ref_body, &proj_own_body);

        Ok((proj_items, proj_impl))
    }

    fn visit_variants(&mut self, variants: &Variants) -> Result<ProjectedVariants> {
        let mut proj_variants = TokenStream::new();
        let mut proj_ref_variants = TokenStream::new();
        let mut proj_own_variants = TokenStream::new();
        let mut proj_arms = TokenStream::new();
        let mut proj_ref_arms = TokenStream::new();
        let mut proj_own_arms = TokenStream::new();

        for Variant { ident, fields, .. } in variants {
            let ProjectedFields {
                proj_pat,
                proj_body,
                proj_fields,
                proj_ref_fields,
                proj_own_fields,
                proj_move,
                proj_drop,
            } = match fields {
                Fields::Named(fields) => self.visit_named(fields)?,
                Fields::Unnamed(fields) => self.visit_unnamed(fields)?,
                Fields::Unit => ProjectedFields::default(),
            };

            let orig_ident = self.orig.ident;
            let proj_ident = &self.proj.mut_ident;
            let proj_ref_ident = &self.proj.ref_ident;
            let proj_own_ident = &self.proj.own_ident;
            proj_variants.extend(quote! {
                #ident #proj_fields,
            });
            proj_ref_variants.extend(quote! {
                #ident #proj_ref_fields,
            });
            proj_own_variants.extend(quote! {
                #ident #proj_own_fields,
            });
            proj_arms.extend(quote! {
                #orig_ident::#ident #proj_pat => {
                    #proj_ident::#ident #proj_body
                }
            });
            proj_ref_arms.extend(quote! {
                #orig_ident::#ident #proj_pat => {
                    #proj_ref_ident::#ident #proj_body
                }
            });
            proj_own_arms.extend(quote! {
                #orig_ident::#ident #proj_pat => {
                    // First, extract all the unpinned fields
                    let __result = #proj_own_ident::#ident #proj_move;

                    // Destructors will run in reverse order, so next create a guard to overwrite
                    // `self` with the replacement value without calling destructors.
                    let __guard = ::pin_project::__private::UnsafeOverwriteGuard {
                        target: __self_ptr,
                        value: ::pin_project::__reexport::mem::ManuallyDrop::new(__replacement),
                    };

                    // Now create guards to drop all the pinned fields
                    //
                    // Due to a compiler bug (https://github.com/rust-lang/rust/issues/47949)
                    // this must be in its own scope, or else `__result` will not be dropped
                    // if any of the destructors panic.
                    {
                        #( let __guard = ::pin_project::__private::UnsafeDropInPlaceGuard(#proj_drop); )*
                    }

                    // Finally, return the result
                    __result
                }
            });
        }

        Ok(ProjectedVariants {
            proj_variants,
            proj_ref_variants,
            proj_own_variants,
            proj_arms,
            proj_ref_arms,
            proj_own_arms,
        })
    }

    fn visit_named(
        &mut self,
        FieldsNamed { named: fields, .. }: &FieldsNamed,
    ) -> Result<ProjectedFields> {
        let mut proj_pat = Vec::with_capacity(fields.len());
        let mut proj_body = Vec::with_capacity(fields.len());
        let mut proj_fields = Vec::with_capacity(fields.len());
        let mut proj_ref_fields = Vec::with_capacity(fields.len());
        let mut proj_own_fields = Vec::with_capacity(fields.len());
        let mut proj_move = Vec::with_capacity(fields.len());
        let mut proj_drop = Vec::with_capacity(fields.len());

        for Field { attrs, vis, ident, ty, .. } in fields {
            if attrs.position_exact(PIN)?.is_some() {
                self.pinned_fields.push(ty.clone());
                proj_drop.push(ident.as_ref().cloned().unwrap());

                let lifetime = &self.proj.lifetime;
                proj_fields.push(
                    quote!(#vis #ident: ::pin_project::__reexport::pin::Pin<&#lifetime mut (#ty)>),
                );
                proj_ref_fields.push(
                    quote!(#vis #ident: ::pin_project::__reexport::pin::Pin<&#lifetime (#ty)>),
                );
                proj_own_fields
                    .push(quote!(#vis #ident: ::pin_project::__reexport::marker::PhantomData<#ty>));
                proj_body.push(
                    quote!(#ident: ::pin_project::__reexport::pin::Pin::new_unchecked(#ident)),
                );
                proj_move.push(quote!(#ident: ::pin_project::__reexport::marker::PhantomData));
            } else {
                let lifetime = &self.proj.lifetime;
                proj_fields.push(quote!(#vis #ident: &#lifetime mut (#ty)));
                proj_ref_fields.push(quote!(#vis #ident: &#lifetime (#ty)));
                proj_own_fields.push(quote!(#vis #ident: #ty));
                proj_body.push(quote!(#ident));
                proj_move.push(quote!(#ident: ::pin_project::__reexport::ptr::read(#ident)));
            }
            proj_pat.push(ident);
        }

        let proj_pat = quote!({ #(#proj_pat),* });
        let proj_body = quote!({ #(#proj_body),* });
        let proj_fields = quote!({ #(#proj_fields),* });
        let proj_ref_fields = quote!({ #(#proj_ref_fields),* });
        let proj_own_fields = quote!({ #(#proj_own_fields),* });
        let proj_move = quote!({ #(#proj_move),* });

        Ok(ProjectedFields {
            proj_pat,
            proj_body,
            proj_fields,
            proj_ref_fields,
            proj_own_fields,
            proj_move,
            proj_drop,
        })
    }

    fn visit_unnamed(
        &mut self,
        FieldsUnnamed { unnamed: fields, .. }: &FieldsUnnamed,
    ) -> Result<ProjectedFields> {
        let mut proj_pat = Vec::with_capacity(fields.len());
        let mut proj_body = Vec::with_capacity(fields.len());
        let mut proj_fields = Vec::with_capacity(fields.len());
        let mut proj_ref_fields = Vec::with_capacity(fields.len());
        let mut proj_own_fields = Vec::with_capacity(fields.len());
        let mut proj_move = Vec::with_capacity(fields.len());
        let mut proj_drop = Vec::with_capacity(fields.len());

        for (i, Field { attrs, vis, ty, .. }) in fields.iter().enumerate() {
            let id = format_ident!("_{}", i);
            if attrs.position_exact(PIN)?.is_some() {
                self.pinned_fields.push(ty.clone());
                proj_drop.push(id.clone());

                let lifetime = &self.proj.lifetime;
                proj_fields
                    .push(quote!(#vis ::pin_project::__reexport::pin::Pin<&#lifetime mut (#ty)>));
                proj_ref_fields
                    .push(quote!(#vis ::pin_project::__reexport::pin::Pin<&#lifetime (#ty)>));
                proj_own_fields
                    .push(quote!(#vis ::pin_project::__reexport::marker::PhantomData<#ty>));
                proj_body.push(quote!(::pin_project::__reexport::pin::Pin::new_unchecked(#id)));
                proj_move.push(quote!(::pin_project::__reexport::marker::PhantomData));
            } else {
                let lifetime = &self.proj.lifetime;
                proj_fields.push(quote!(#vis &#lifetime mut (#ty)));
                proj_ref_fields.push(quote!(#vis &#lifetime (#ty)));
                proj_own_fields.push(quote!(#vis #ty));
                proj_body.push(quote!(#id));
                proj_move.push(quote!(::pin_project::__reexport::ptr::read(#id)));
            }
            proj_pat.push(id);
        }

        let proj_pat = quote!((#(#proj_pat),*));
        let proj_body = quote!((#(#proj_body),*));
        let proj_fields = quote!((#(#proj_fields),*));
        let proj_ref_fields = quote!((#(#proj_ref_fields),*));
        let proj_own_fields = quote!((#(#proj_own_fields),*));
        let proj_move = quote!((#(#proj_move),*));

        Ok(ProjectedFields {
            proj_pat,
            proj_body,
            proj_fields,
            proj_ref_fields,
            proj_own_fields,
            proj_move,
            proj_drop,
        })
    }

    /// Creates `Unpin` implementation for original type.
    fn make_unpin_impl(&self) -> TokenStream {
        match self.unpin_impl {
            UnpinImpl::Unsafe(span) => {
                let mut proj_generics = self.proj.generics.clone();
                let orig_ident = self.orig.ident;
                let lifetime = &self.proj.lifetime;

                proj_generics.make_where_clause().predicates.push(
                    // Make the error message highlight `UnsafeUnpin` argument.
                    parse_quote_spanned! { span =>
                        ::pin_project::__private::Wrapper<#lifetime, Self>: ::pin_project::UnsafeUnpin
                    },
                );

                let (impl_generics, _, where_clause) = proj_generics.split_for_impl();
                let ty_generics = self.orig.generics.split_for_impl().1;

                quote! {
                    impl #impl_generics ::pin_project::__reexport::marker::Unpin for #orig_ident #ty_generics #where_clause {}
                }
            }
            UnpinImpl::Negative(span) => {
                let mut proj_generics = self.proj.generics.clone();
                let orig_ident = self.orig.ident;
                let lifetime = &self.proj.lifetime;

                proj_generics.make_where_clause().predicates.push(parse_quote! {
                    ::pin_project::__private::Wrapper<
                        #lifetime, ::pin_project::__reexport::marker::PhantomPinned
                    >: ::pin_project::__reexport::marker::Unpin
                });

                let (proj_impl_generics, _, proj_where_clause) = proj_generics.split_for_impl();
                let (impl_generics, ty_generics, orig_where_clause) =
                    self.orig.generics.split_for_impl();

                // For interoperability with `forbid(unsafe_code)`, `unsafe` token should be call-site span.
                let unsafety = token::Unsafe::default();
                quote_spanned! { span =>
                    impl #proj_impl_generics ::pin_project::__reexport::marker::Unpin for #orig_ident #ty_generics #proj_where_clause {}

                    // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
                    //
                    // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
                    // impls, we emit one ourselves. If the user ends up writing a `UnsafeUnpin` impl,
                    // they'll get a "conflicting implementations of trait" error when coherence
                    // checks are run.
                    #unsafety impl #impl_generics ::pin_project::UnsafeUnpin for #orig_ident #ty_generics #orig_where_clause {}
                }
            }
            UnpinImpl::Default => {
                let mut full_where_clause =
                    self.orig.generics.where_clause.as_ref().cloned().unwrap();

                // Generate a field in our new struct for every
                // pinned field in the original type.
                let fields = self.pinned_fields.iter().enumerate().map(|(i, ty)| {
                    let field_ident = format_ident!("__field{}", i);
                    quote!(#field_ident: #ty)
                });

                // We could try to determine the subset of type parameters
                // and lifetimes that are actually used by the pinned fields
                // (as opposed to those only used by unpinned fields).
                // However, this would be tricky and error-prone, since
                // it's possible for users to create types that would alias
                // with generic parameters (e.g. 'struct T').
                //
                // Instead, we generate a use of every single type parameter
                // and lifetime used in the original struct. For type parameters,
                // we generate code like this:
                //
                // ```rust
                // struct AlwaysUnpin<T: ?Sized>(PhantomData<T>) {}
                // impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
                //
                // ...
                // _field: AlwaysUnpin<(A, B, C)>
                // ```
                //
                // This ensures that any unused type parameters
                // don't end up with `Unpin` bounds.
                let lifetime_fields = self.orig.generics.lifetimes().enumerate().map(
                    |(i, LifetimeDef { lifetime, .. })| {
                        let field_ident = format_ident!("__lifetime{}", i);
                        quote!(#field_ident: &#lifetime ())
                    },
                );

                let orig_ident = self.orig.ident;
                let struct_ident = format_ident!("__{}", orig_ident);
                let vis = self.orig.vis;
                let lifetime = &self.proj.lifetime;
                let type_params = self.orig.generics.type_params().map(|t| &t.ident);
                let proj_generics = &self.proj.generics;
                let (proj_impl_generics, proj_ty_generics, _) = proj_generics.split_for_impl();
                let (impl_generics, ty_generics, where_clause) =
                    self.orig.generics.split_for_impl();

                full_where_clause.predicates.push(syn::parse_quote! {
                    #struct_ident #proj_ty_generics: ::pin_project::__reexport::marker::Unpin
                });

                quote! {
                    // This needs to have the same visibility as the original type,
                    // due to the limitations of the 'public in private' error.
                    //
                    // Our goal is to implement the public trait `Unpin` for
                    // a potentially public user type. Because of this, rust
                    // requires that any types mentioned in the where clause of
                    // our `Unpin` impl also be public. This means that our generated
                    // `__UnpinStruct` type must also be public.
                    // However, we ensure that the user can never actually reference
                    // this 'public' type by creating this type in the inside of `const`.
                    #vis struct #struct_ident #proj_generics #where_clause {
                        __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<#lifetime, (#(#type_params),*)>,

                        #(#fields,)*
                        #(#lifetime_fields,)*
                    }

                    impl #proj_impl_generics ::pin_project::__reexport::marker::Unpin for #orig_ident #ty_generics #full_where_clause {}

                    // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
                    //
                    // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
                    // impls, we emit one ourselves. If the user ends up writing a `UnsafeUnpin` impl,
                    // they'll get a "conflicting implementations of trait" error when coherence
                    // checks are run.
                    unsafe impl #impl_generics ::pin_project::UnsafeUnpin for #orig_ident #ty_generics #where_clause {}
                }
            }
        }
    }

    /// Creates `Drop` implementation for original type.
    fn make_drop_impl(&self) -> TokenStream {
        let ident = self.orig.ident;
        let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();

        if let Some(pinned_drop) = self.pinned_drop {
            // For interoperability with `forbid(unsafe_code)`, `unsafe` token should be call-site span.
            let unsafety = token::Unsafe::default();
            quote_spanned! { pinned_drop =>
                impl #impl_generics ::pin_project::__reexport::ops::Drop for #ident #ty_generics #where_clause {
                    fn drop(&mut self) {
                        // Safety - we're in 'drop', so we know that 'self' will
                        // never move again.
                        let pinned_self = #unsafety { ::pin_project::__reexport::pin::Pin::new_unchecked(self) };
                        // We call `pinned_drop` only once. Since `PinnedDrop::drop`
                        // is an unsafe method and a private API, it is never called again in safe
                        // code *unless the user uses a maliciously crafted macro*.
                        #unsafety {
                            ::pin_project::__private::PinnedDrop::drop(pinned_self);
                        }
                    }
                }
            }
        } else {
            // If the user does not provide a `PinnedDrop` impl,
            // we need to ensure that they don't provide a `Drop` impl of their
            // own.
            // Based on https://github.com/upsuper/assert-impl/blob/f503255b292ab0ba8d085b657f4065403cfa46eb/src/lib.rs#L80-L87
            //
            // We create a new identifier for each struct, so that the traits
            // for different types do not conflict with each other.
            //
            // Another approach would be to provide an empty Drop impl,
            // which would conflict with a user-provided Drop impl.
            // However, this would trigger the compiler's special handling
            // of Drop types (e.g. fields cannot be moved out of a Drop type).
            // This approach prevents the creation of needless Drop impls,
            // giving users more flexibility.
            let trait_ident = format_ident!("{}MustNotImplDrop", ident);

            quote! {
                // There are two possible cases:
                // 1. The user type does not implement Drop. In this case,
                // the first blanked impl will not apply to it. This code
                // will compile, as there is only one impl of MustNotImplDrop for the user type
                // 2. The user type does impl Drop. This will make the blanket impl applicable,
                // which will then conflict with the explicit MustNotImplDrop impl below.
                // This will result in a compilation error, which is exactly what we want.
                trait #trait_ident {}
                #[allow(clippy::drop_bounds)]
                impl<T: ::pin_project::__reexport::ops::Drop> #trait_ident for T {}
                impl #impl_generics #trait_ident for #ident #ty_generics #where_clause {}

                // A dummy impl of `PinnedDrop`, to ensure that the user cannot implement it.
                // Since the user did not pass `PinnedDrop` to `#[pin_project]`, any `PinnedDrop`
                // impl will not actually be called. Unfortunately, we can't detect this situation
                // directly from either the `#[pin_project]` or `#[pinned_drop]` attributes, since
                // we don't know what other attirbutes/impl may exist.
                //
                // To ensure that users don't accidentally write a non-functional `PinnedDrop`
                // impls, we emit one ourselves. If the user ends up writing a `PinnedDrop` impl,
                // they'll get a "conflicting implementations of trait" error when coherence
                // checks are run.
                impl #impl_generics ::pin_project::__private::PinnedDrop for #ident #ty_generics #where_clause {
                    unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
                }
            }
        }
    }

    /// Creates an implementation of the projection method.
    fn make_proj_impl(
        &self,
        proj_body: &TokenStream,
        proj_ref_body: &TokenStream,
        proj_own_body: &TokenStream,
    ) -> TokenStream {
        let vis = &self.proj.vis;
        let lifetime = &self.proj.lifetime;
        let orig_ident = self.orig.ident;
        let proj_ident = &self.proj.mut_ident;
        let proj_ref_ident = &self.proj.ref_ident;
        let proj_own_ident = &self.proj.own_ident;

        let orig_ty_generics = self.orig.generics.split_for_impl().1;
        let proj_ty_generics = self.proj.generics.split_for_impl().1;
        let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();

        let replace_impl = self.replace.map(|_| {
            // Currently, using quote_spanned here does not seem to have any effect on the diagnostics.
            quote! {
                #vis fn project_replace(
                    self: ::pin_project::__reexport::pin::Pin<&mut Self>,
                    __replacement: Self,
                ) -> #proj_own_ident #orig_ty_generics {
                    unsafe {
                        #proj_own_body
                    }
                }
            }
        });

        quote! {
            impl #impl_generics #orig_ident #ty_generics #where_clause {
                #vis fn project<#lifetime>(
                    self: ::pin_project::__reexport::pin::Pin<&#lifetime mut Self>,
                ) -> #proj_ident #proj_ty_generics {
                    unsafe {
                        #proj_body
                    }
                }
                #vis fn project_ref<#lifetime>(
                    self: ::pin_project::__reexport::pin::Pin<&#lifetime Self>,
                ) -> #proj_ref_ident #proj_ty_generics {
                    unsafe {
                        #proj_ref_body
                    }
                }
                #replace_impl
            }
        }
    }

    fn ensure_not_packed(&self, fields: &Fields) -> Result<TokenStream> {
        for meta in self.orig.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) {
            if let Meta::List(l) = meta {
                if l.path.is_ident("repr") {
                    for repr in l.nested.iter() {
                        match repr {
                            NestedMeta::Meta(Meta::Path(path))
                            | NestedMeta::Meta(Meta::List(MetaList { path, .. }))
                                if path.is_ident("packed") =>
                            {
                                return Err(error!(
                                    repr,
                                    "#[pin_project] attribute may not be used on #[repr(packed)] types"
                                ));
                            }
                            _ => {}
                        }
                    }
                }
            }
        }

        // As proc-macro-derive can't rewrite the structure definition,
        // it's probably no longer necessary, but it keeps it for now.

        // Workaround for https://github.com/taiki-e/pin-project/issues/32
        // Through the tricky use of proc macros, it's possible to bypass
        // the above check for the `repr` attribute.
        // To ensure that it's impossible to use pin projections on a `#[repr(packed)]`
        // struct, we generate code like this:
        //
        // ```rust
        // #[deny(safe_packed_borrows)]
        // fn assert_not_repr_packed(val: &MyStruct) {
        //     let _field1 = &val.field1;
        //     let _field2 = &val.field2;
        //     ...
        //     let _fieldn = &val.fieldn;
        // }
        // ```
        //
        // Taking a reference to a packed field is unsafe, and applying
        // `#[deny(safe_packed_borrows)]` makes sure that doing this without
        // an `unsafe` block (which we deliberately do not generate)
        // is a hard error.
        //
        // If the struct ends up having `#[repr(packed)]` applied somehow,
        // this will generate an (unfriendly) error message. Under all reasonable
        // circumstances, we'll detect the `#[repr(packed)]` attribute, and generate
        // a much nicer error above.
        //
        // There is one exception: If the type of a struct field has an alignment of 1
        // (e.g. u8), it is always safe to take a reference to it, even if the struct
        // is `#[repr(packed)]`. If the struct is composed entirely of types of alignment 1,
        // our generated method will not trigger an error if the struct is `#[repr(packed)]`.
        //
        // Fortunately, this should have no observable consequence - `#[repr(packed)]`
        // is essentially a no-op on such a type. Nevertheless, we include a test
        // to ensure that the compiler doesn't ever try to copy the fields on
        // such a struct when trying to drop it - which is reason we prevent
        // `#[repr(packed)]` in the first place.
        //
        // See also https://github.com/taiki-e/pin-project/pull/34.
        let mut field_refs = vec![];
        match fields {
            Fields::Named(FieldsNamed { named, .. }) => {
                for Field { ident, .. } in named {
                    field_refs.push(quote!(&val.#ident;));
                }
            }
            Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
                for (index, _) in unnamed.iter().enumerate() {
                    let index = Index::from(index);
                    field_refs.push(quote!(&val.#index;));
                }
            }
            Fields::Unit => {}
        }

        let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();
        let ident = self.orig.ident;
        Ok(quote! {
            #[deny(safe_packed_borrows)]
            fn __assert_not_repr_packed #impl_generics (val: &#ident #ty_generics) #where_clause {
                #(#field_refs)*
            }
        })
    }
}
