#![recursion_limit = "256"]
// Copyright (c) 2020 Google LLC All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/// Implementation of the `FromArgs` and `argh(...)` derive attributes.
///
/// For more thorough documentation, see the `argh` crate itself.
extern crate proc_macro;

use {
    crate::{
        errors::Errors,
        parse_attrs::{FieldAttrs, FieldKind, TypeAttrs},
    },
    proc_macro2::{Span, TokenStream},
    quote::{quote, quote_spanned, ToTokens},
    std::str::FromStr,
    syn::{spanned::Spanned, LitStr},
};

mod errors;
mod help;
mod parse_attrs;

/// Entrypoint for `#[derive(FromArgs)]`.
#[proc_macro_derive(FromArgs, attributes(argh))]
pub fn argh_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let ast = syn::parse_macro_input!(input as syn::DeriveInput);
    let gen = impl_from_args(&ast);
    gen.into()
}

/// Transform the input into a token stream containing any generated implementations,
/// as well as all errors that occurred.
fn impl_from_args(input: &syn::DeriveInput) -> TokenStream {
    let errors = &Errors::default();
    if input.generics.params.len() != 0 {
        errors.err(
            &input.generics,
            "`#![derive(FromArgs)]` cannot be applied to types with generic parameters",
        );
    }
    let type_attrs = &TypeAttrs::parse(errors, input);
    let mut output_tokens = match &input.data {
        syn::Data::Struct(ds) => impl_from_args_struct(errors, &input.ident, type_attrs, ds),
        syn::Data::Enum(de) => impl_from_args_enum(errors, &input.ident, type_attrs, de),
        syn::Data::Union(_) => {
            errors.err(input, "`#[derive(FromArgs)]` cannot be applied to unions");
            TokenStream::new()
        }
    };
    errors.to_tokens(&mut output_tokens);
    output_tokens
}

/// The kind of optionality a parameter has.
enum Optionality {
    None,
    Defaulted(TokenStream),
    Optional,
    Repeating,
}

impl PartialEq<Optionality> for Optionality {
    fn eq(&self, other: &Optionality) -> bool {
        use Optionality::*;
        match (self, other) {
            (None, None) | (Optional, Optional) | (Repeating, Repeating) => true,
            // NB: (Defaulted, Defaulted) can't contain the same token streams
            _ => false,
        }
    }
}

impl Optionality {
    /// Whether or not this is `Optionality::None`
    fn is_required(&self) -> bool {
        if let Optionality::None = self {
            true
        } else {
            false
        }
    }
}

/// A field of a `#![derive(FromArgs)]` struct with attributes and some other
/// notable metadata appended.
struct StructField<'a> {
    /// The original parsed field
    field: &'a syn::Field,
    /// The parsed attributes of the field
    attrs: FieldAttrs,
    /// The field name. This is contained optionally inside `field`,
    /// but is duplicated non-optionally here to indicate that all field that
    /// have reached this point must have a field name, and it no longer
    /// needs to be unwrapped.
    name: &'a syn::Ident,
    /// Similar to `name` above, this is contained optionally inside `FieldAttrs`,
    /// but here is fully present to indicate that we only have to consider fields
    /// with a valid `kind` at this point.
    kind: FieldKind,
    // If `field.ty` is `Vec<T>` or `Option<T>`, this is `T`, otherwise it's `&field.ty`.
    // This is used to enable consistent parsing code between optional and non-optional
    // keyed and subcommand fields.
    ty_without_wrapper: &'a syn::Type,
    // Whether the field represents an optional value, such as an `Option` subcommand field
    // or an `Option` or `Vec` keyed argument, or if it has a `default`.
    optionality: Optionality,
    // The `--`-prefixed name of the option, if one exists.
    long_name: Option<String>,
}

impl<'a> StructField<'a> {
    /// Attempts to parse a field of a `#[derive(FromArgs)]` struct, pulling out the
    /// fields required for code generation.
    fn new(errors: &Errors, field: &'a syn::Field, attrs: FieldAttrs) -> Option<Self> {
        let name = field.ident.as_ref().expect("missing ident for named field");

        // Ensure that one "kind" is present (switch, option, subcommand, positional)
        let kind = if let Some(field_type) = &attrs.field_type {
            field_type.kind
        } else {
            errors.err(
                field,
                concat!(
                    "Missing `argh` field kind attribute.\n",
                    "Expected one of: `switch`, `option`, `subcommand`, `positional`",
                ),
            );
            return None;
        };

        // Parse out whether a field is optional (`Option` or `Vec`).
        let optionality;
        let ty_without_wrapper;
        match kind {
            FieldKind::Switch => {
                if !ty_expect_switch(errors, &field.ty) {
                    return None;
                }
                optionality = Optionality::Optional;
                ty_without_wrapper = &field.ty;
            }
            FieldKind::Option | FieldKind::Positional => {
                if let Some(default) = &attrs.default {
                    let tokens = match TokenStream::from_str(&default.value()) {
                        Ok(tokens) => tokens,
                        Err(_) => {
                            errors.err(&default, "Invalid tokens: unable to lex `default` value");
                            return None;
                        }
                    };
                    // Set the span of the generated tokens to the string literal
                    let tokens: TokenStream = tokens
                        .into_iter()
                        .map(|mut tree| {
                            tree.set_span(default.span());
                            tree
                        })
                        .collect();
                    optionality = Optionality::Defaulted(tokens);
                    ty_without_wrapper = &field.ty;
                } else {
                    let mut inner = None;
                    optionality = if let Some(x) = ty_inner(&["Option"], &field.ty) {
                        inner = Some(x);
                        Optionality::Optional
                    } else if let Some(x) = ty_inner(&["Vec"], &field.ty) {
                        inner = Some(x);
                        Optionality::Repeating
                    } else {
                        Optionality::None
                    };
                    ty_without_wrapper = inner.unwrap_or(&field.ty);
                }
            }
            FieldKind::SubCommand => {
                let inner = ty_inner(&["Option"], &field.ty);
                optionality =
                    if inner.is_some() { Optionality::Optional } else { Optionality::None };
                ty_without_wrapper = inner.unwrap_or(&field.ty);
            }
        }

        // Determine the "long" name of options and switches.
        // Defaults to the kebab-case'd field name if `#[argh(long = "...")]` is omitted.
        let long_name = match kind {
            FieldKind::Switch | FieldKind::Option => {
                let long_name = attrs
                    .long
                    .as_ref()
                    .map(syn::LitStr::value)
                    .unwrap_or_else(|| heck::KebabCase::to_kebab_case(&*name.to_string()));
                if long_name == "help" {
                    errors.err(field, "Custom `--help` flags are not supported.");
                }
                let long_name = format!("--{}", long_name);
                Some(long_name)
            }
            FieldKind::SubCommand | FieldKind::Positional => None,
        };

        Some(StructField { field, attrs, kind, optionality, ty_without_wrapper, name, long_name })
    }

    pub(crate) fn arg_name(&self) -> String {
        self.attrs.arg_name.as_ref().map(LitStr::value).unwrap_or_else(|| self.name.to_string())
    }
}

/// Implements `FromArgs` and `TopLevelCommand` or `SubCommand` for a `#[derive(FromArgs)]` struct.
fn impl_from_args_struct(
    errors: &Errors,
    name: &syn::Ident,
    type_attrs: &TypeAttrs,
    ds: &syn::DataStruct,
) -> TokenStream {
    let fields = match &ds.fields {
        syn::Fields::Named(fields) => fields,
        syn::Fields::Unnamed(_) => {
            errors.err(
                &ds.struct_token,
                "`#![derive(FromArgs)]` is not currently supported on tuple structs",
            );
            return TokenStream::new();
        }
        syn::Fields::Unit => {
            errors.err(&ds.struct_token, "#![derive(FromArgs)]` cannot be applied to unit structs");
            return TokenStream::new();
        }
    };

    let fields: Vec<_> = fields
        .named
        .iter()
        .filter_map(|field| {
            let attrs = FieldAttrs::parse(errors, field);
            StructField::new(errors, field, attrs)
        })
        .collect();

    ensure_only_last_positional_is_optional(errors, &fields);

    let impl_span = Span::call_site();

    let from_args_method = impl_from_args_struct_from_args(errors, type_attrs, &fields);

    let redact_arg_values_method =
        impl_from_args_struct_redact_arg_values(errors, type_attrs, &fields);

    let top_or_sub_cmd_impl = top_or_sub_cmd_impl(errors, name, type_attrs);

    let trait_impl = quote_spanned! { impl_span =>
        impl argh::FromArgs for #name {
            #from_args_method

            #redact_arg_values_method
        }

        #top_or_sub_cmd_impl
    };

    trait_impl
}

fn impl_from_args_struct_from_args<'a>(
    errors: &Errors,
    type_attrs: &TypeAttrs,
    fields: &'a [StructField<'a>],
) -> TokenStream {
    let init_fields = declare_local_storage_for_from_args_fields(&fields);
    let unwrap_fields = unwrap_from_args_fields(&fields);
    let positional_fields: Vec<&StructField<'_>> =
        fields.iter().filter(|field| field.kind == FieldKind::Positional).collect();
    let positional_field_idents = positional_fields.iter().map(|field| &field.field.ident);
    let positional_field_names = positional_fields.iter().map(|field| field.name.to_string());
    let last_positional_is_repeating = positional_fields
        .last()
        .map(|field| field.optionality == Optionality::Repeating)
        .unwrap_or(false);

    let flag_output_table = fields.iter().filter_map(|field| {
        let field_name = &field.field.ident;
        match field.kind {
            FieldKind::Option => Some(quote! { argh::ParseStructOption::Value(&mut #field_name) }),
            FieldKind::Switch => Some(quote! { argh::ParseStructOption::Flag(&mut #field_name) }),
            FieldKind::SubCommand | FieldKind::Positional => None,
        }
    });

    let flag_str_to_output_table_map = flag_str_to_output_table_map_entries(&fields);

    let mut subcommands_iter =
        fields.iter().filter(|field| field.kind == FieldKind::SubCommand).fuse();

    let subcommand: Option<&StructField<'_>> = subcommands_iter.next();
    while let Some(dup_subcommand) = subcommands_iter.next() {
        errors.duplicate_attrs("subcommand", subcommand.unwrap().field, dup_subcommand.field);
    }

    let impl_span = Span::call_site();

    let missing_requirements_ident = syn::Ident::new("__missing_requirements", impl_span);

    let append_missing_requirements =
        append_missing_requirements(&missing_requirements_ident, &fields);

    let parse_subcommands = if let Some(subcommand) = subcommand {
        let name = subcommand.name;
        let ty = subcommand.ty_without_wrapper;
        quote_spanned! { impl_span =>
            Some(argh::ParseStructSubCommand {
                subcommands: <#ty as argh::SubCommands>::COMMANDS,
                parse_func: &mut |__command, __remaining_args| {
                    #name = Some(<#ty as argh::FromArgs>::from_args(__command, __remaining_args)?);
                    Ok(())
                },
            })
        }
    } else {
        quote_spanned! { impl_span => None }
    };

    // Identifier referring to a value containing the name of the current command as an `&[&str]`.
    let cmd_name_str_array_ident = syn::Ident::new("__cmd_name", impl_span);
    let help = help::help(errors, cmd_name_str_array_ident, type_attrs, &fields, subcommand);

    let method_impl = quote_spanned! { impl_span =>
        fn from_args(__cmd_name: &[&str], __args: &[&str])
            -> std::result::Result<Self, argh::EarlyExit>
        {
            #( #init_fields )*

            argh::parse_struct_args(
                __cmd_name,
                __args,
                argh::ParseStructOptions {
                    arg_to_slot: &[ #( #flag_str_to_output_table_map ,)* ],
                    slots: &mut [ #( #flag_output_table, )* ],
                },
                argh::ParseStructPositionals {
                    positionals: &mut [
                        #(
                            argh::ParseStructPositional {
                                name: #positional_field_names,
                                slot: &mut #positional_field_idents as &mut argh::ParseValueSlot,
                            },
                        )*
                    ],
                    last_is_repeating: #last_positional_is_repeating,
                },
                #parse_subcommands,
                &|| #help,
            )?;

            let mut #missing_requirements_ident = argh::MissingRequirements::default();
            #(
                #append_missing_requirements
            )*
            #missing_requirements_ident.err_on_any()?;

            Ok(Self {
                #( #unwrap_fields, )*
            })
        }
    };

    method_impl
}

fn impl_from_args_struct_redact_arg_values<'a>(
    errors: &Errors,
    type_attrs: &TypeAttrs,
    fields: &'a [StructField<'a>],
) -> TokenStream {
    let init_fields = declare_local_storage_for_redacted_fields(&fields);
    let unwrap_fields = unwrap_redacted_fields(&fields);

    let positional_fields: Vec<&StructField<'_>> =
        fields.iter().filter(|field| field.kind == FieldKind::Positional).collect();
    let positional_field_idents = positional_fields.iter().map(|field| &field.field.ident);
    let positional_field_names = positional_fields.iter().map(|field| field.name.to_string());
    let last_positional_is_repeating = positional_fields
        .last()
        .map(|field| field.optionality == Optionality::Repeating)
        .unwrap_or(false);

    let flag_output_table = fields.iter().filter_map(|field| {
        let field_name = &field.field.ident;
        match field.kind {
            FieldKind::Option => Some(quote! { argh::ParseStructOption::Value(&mut #field_name) }),
            FieldKind::Switch => Some(quote! { argh::ParseStructOption::Flag(&mut #field_name) }),
            FieldKind::SubCommand | FieldKind::Positional => None,
        }
    });

    let flag_str_to_output_table_map = flag_str_to_output_table_map_entries(&fields);

    let mut subcommands_iter =
        fields.iter().filter(|field| field.kind == FieldKind::SubCommand).fuse();

    let subcommand: Option<&StructField<'_>> = subcommands_iter.next();
    while let Some(dup_subcommand) = subcommands_iter.next() {
        errors.duplicate_attrs("subcommand", subcommand.unwrap().field, dup_subcommand.field);
    }

    let impl_span = Span::call_site();

    let missing_requirements_ident = syn::Ident::new("__missing_requirements", impl_span);

    let append_missing_requirements =
        append_missing_requirements(&missing_requirements_ident, &fields);

    let redact_subcommands = if let Some(subcommand) = subcommand {
        let name = subcommand.name;
        let ty = subcommand.ty_without_wrapper;
        quote_spanned! { impl_span =>
            Some(argh::ParseStructSubCommand {
                subcommands: <#ty as argh::SubCommands>::COMMANDS,
                parse_func: &mut |__command, __remaining_args| {
                    #name = Some(<#ty as argh::FromArgs>::redact_arg_values(__command, __remaining_args)?);
                    Ok(())
                },
            })
        }
    } else {
        quote_spanned! { impl_span => None }
    };

    let cmd_name = if type_attrs.is_subcommand.is_none() {
        quote! { __cmd_name.last().expect("no command name").to_string() }
    } else {
        quote! { __cmd_name.last().expect("no subcommand name").to_string() }
    };

    // Identifier referring to a value containing the name of the current command as an `&[&str]`.
    let cmd_name_str_array_ident = syn::Ident::new("__cmd_name", impl_span);
    let help = help::help(errors, cmd_name_str_array_ident, type_attrs, &fields, subcommand);

    let method_impl = quote_spanned! { impl_span =>
        fn redact_arg_values(__cmd_name: &[&str], __args: &[&str]) -> std::result::Result<Vec<String>, argh::EarlyExit> {
            #( #init_fields )*

            argh::parse_struct_args(
                __cmd_name,
                __args,
                argh::ParseStructOptions {
                    arg_to_slot: &[ #( #flag_str_to_output_table_map ,)* ],
                    slots: &mut [ #( #flag_output_table, )* ],
                },
                argh::ParseStructPositionals {
                    positionals: &mut [
                        #(
                            argh::ParseStructPositional {
                                name: #positional_field_names,
                                slot: &mut #positional_field_idents as &mut argh::ParseValueSlot,
                            },
                        )*
                    ],
                    last_is_repeating: #last_positional_is_repeating,
                },
                #redact_subcommands,
                &|| #help,
            )?;

            let mut #missing_requirements_ident = argh::MissingRequirements::default();
            #(
                #append_missing_requirements
            )*
            #missing_requirements_ident.err_on_any()?;

            let mut __redacted = vec![
                #cmd_name,
            ];

            #( #unwrap_fields )*

            Ok(__redacted)
        }
    };

    method_impl
}

/// Ensures that only the last positional arg is non-required.
fn ensure_only_last_positional_is_optional(errors: &Errors, fields: &[StructField<'_>]) {
    let mut first_non_required_span = None;
    for field in fields {
        if field.kind == FieldKind::Positional {
            if let Some(first) = first_non_required_span {
                errors.err_span(
                    first,
                    "Only the last positional argument may be `Option`, `Vec`, or defaulted.",
                );
                errors.err(&field.field, "Later positional argument declared here.");
                return;
            }
            if !field.optionality.is_required() {
                first_non_required_span = Some(field.field.span());
            }
        }
    }
}

/// Implement `argh::TopLevelCommand` or `argh::SubCommand` as appropriate.
fn top_or_sub_cmd_impl(errors: &Errors, name: &syn::Ident, type_attrs: &TypeAttrs) -> TokenStream {
    let description =
        help::require_description(errors, name.span(), &type_attrs.description, "type");
    if type_attrs.is_subcommand.is_none() {
        // Not a subcommand
        quote! {
            impl argh::TopLevelCommand for #name {}
        }
    } else {
        let empty_str = syn::LitStr::new("", Span::call_site());
        let subcommand_name = type_attrs.name.as_ref().unwrap_or_else(|| {
            errors.err(name, "`#[argh(name = \"...\")]` attribute is required for subcommands");
            &empty_str
        });
        quote! {
            impl argh::SubCommand for #name {
                const COMMAND: &'static argh::CommandInfo = &argh::CommandInfo {
                    name: #subcommand_name,
                    description: #description,
                };
            }
        }
    }
}

/// Declare a local slots to store each field in during parsing.
///
/// Most fields are stored in `Option<FieldType>` locals.
/// `argh(option)` fields are stored in a `ParseValueSlotTy` along with a
/// function that knows how to decode the appropriate value.
fn declare_local_storage_for_from_args_fields<'a>(
    fields: &'a [StructField<'a>],
) -> impl Iterator<Item = TokenStream> + 'a {
    fields.iter().map(|field| {
        let field_name = &field.field.ident;
        let field_type = &field.ty_without_wrapper;

        // Wrap field types in `Option` if they aren't already `Option` or `Vec`-wrapped.
        let field_slot_type = match field.optionality {
            Optionality::Optional | Optionality::Repeating => (&field.field.ty).into_token_stream(),
            Optionality::None | Optionality::Defaulted(_) => {
                quote! { std::option::Option<#field_type> }
            }
        };

        match field.kind {
            FieldKind::Option | FieldKind::Positional => {
                let from_str_fn = match &field.attrs.from_str_fn {
                    Some(from_str_fn) => from_str_fn.into_token_stream(),
                    None => {
                        quote! {
                            <#field_type as argh::FromArgValue>::from_arg_value
                        }
                    }
                };

                quote! {
                    let mut #field_name: argh::ParseValueSlotTy<#field_slot_type, #field_type>
                        = argh::ParseValueSlotTy {
                            slot: std::default::Default::default(),
                            parse_func: |_, value| { #from_str_fn(value) },
                        };
                }
            }
            FieldKind::SubCommand => {
                quote! { let mut #field_name: #field_slot_type = None; }
            }
            FieldKind::Switch => {
                quote! { let mut #field_name: #field_slot_type = argh::Flag::default(); }
            }
        }
    })
}

/// Unwrap non-optional fields and take options out of their tuple slots.
fn unwrap_from_args_fields<'a>(
    fields: &'a [StructField<'a>],
) -> impl Iterator<Item = TokenStream> + 'a {
    fields.iter().map(|field| {
        let field_name = field.name;
        match field.kind {
            FieldKind::Option | FieldKind::Positional => match &field.optionality {
                Optionality::None => quote! { #field_name: #field_name.slot.unwrap() },
                Optionality::Optional | Optionality::Repeating => {
                    quote! { #field_name: #field_name.slot }
                }
                Optionality::Defaulted(tokens) => {
                    quote! {
                        #field_name: #field_name.slot.unwrap_or_else(|| #tokens)
                    }
                }
            },
            FieldKind::Switch => field_name.into_token_stream(),
            FieldKind::SubCommand => match field.optionality {
                Optionality::None => quote! { #field_name: #field_name.unwrap() },
                Optionality::Optional | Optionality::Repeating => field_name.into_token_stream(),
                Optionality::Defaulted(_) => unreachable!(),
            },
        }
    })
}

/// Declare a local slots to store each field in during parsing.
///
/// Most fields are stored in `Option<FieldType>` locals.
/// `argh(option)` fields are stored in a `ParseValueSlotTy` along with a
/// function that knows how to decode the appropriate value.
fn declare_local_storage_for_redacted_fields<'a>(
    fields: &'a [StructField<'a>],
) -> impl Iterator<Item = TokenStream> + 'a {
    fields.iter().map(|field| {
        let field_name = &field.field.ident;

        match field.kind {
            FieldKind::Switch => {
                quote! {
                    let mut #field_name = argh::RedactFlag {
                        slot: None,
                    };
                }
            }
            FieldKind::Option => {
                let field_slot_type = match field.optionality {
                    Optionality::Repeating => {
                        quote! { std::vec::Vec<String> }
                    }
                    Optionality::None | Optionality::Optional | Optionality::Defaulted(_) => {
                        quote! { std::option::Option<String> }
                    }
                };

                quote! {
                    let mut #field_name: argh::ParseValueSlotTy::<#field_slot_type, String> =
                        argh::ParseValueSlotTy {
                        slot: std::default::Default::default(),
                        parse_func: |arg, _| { Ok(arg.to_string()) },
                    };
                }
            }
            FieldKind::Positional => {
                let field_slot_type = match field.optionality {
                    Optionality::Repeating => {
                        quote! { std::vec::Vec<String> }
                    }
                    Optionality::None | Optionality::Optional | Optionality::Defaulted(_) => {
                        quote! { std::option::Option<String> }
                    }
                };

                let arg_name = field.arg_name();
                quote! {
                    let mut #field_name: argh::ParseValueSlotTy::<#field_slot_type, String> =
                        argh::ParseValueSlotTy {
                        slot: std::default::Default::default(),
                        parse_func: |_, _| { Ok(#arg_name.to_string()) },
                    };
                }
            }
            FieldKind::SubCommand => {
                quote! { let mut #field_name: std::option::Option<std::vec::Vec<String>> = None; }
            }
        }
    })
}

/// Unwrap non-optional fields and take options out of their tuple slots.
fn unwrap_redacted_fields<'a>(
    fields: &'a [StructField<'a>],
) -> impl Iterator<Item = TokenStream> + 'a {
    fields.iter().map(|field| {
        let field_name = field.name;

        match field.kind {
            FieldKind::Switch => {
                quote! {
                    if let Some(__field_name) = #field_name.slot {
                        __redacted.push(__field_name);
                    }
                }
            }
            FieldKind::Option => match field.optionality {
                Optionality::Repeating => {
                    quote! {
                        __redacted.extend(#field_name.slot.into_iter());
                    }
                }
                Optionality::None | Optionality::Optional | Optionality::Defaulted(_) => {
                    quote! {
                        if let Some(__field_name) = #field_name.slot {
                            __redacted.push(__field_name);
                        }
                    }
                }
            },
            FieldKind::Positional => {
                quote! {
                    __redacted.extend(#field_name.slot.into_iter());
                }
            }
            FieldKind::SubCommand => {
                quote! {
                    if let Some(__subcommand_args) = #field_name {
                        __redacted.extend(__subcommand_args.into_iter());
                    }
                }
            }
        }
    })
}

/// Entries of tokens like `("--some-flag-key", 5)` that map from a flag key string
/// to an index in the output table.
fn flag_str_to_output_table_map_entries<'a>(fields: &'a [StructField<'a>]) -> Vec<TokenStream> {
    let mut flag_str_to_output_table_map = vec![];
    for (i, (field, long_name)) in fields
        .iter()
        .filter_map(|field| field.long_name.as_ref().map(|long_name| (field, long_name)))
        .enumerate()
    {
        if let Some(short) = &field.attrs.short {
            let short = format!("-{}", short.value());
            flag_str_to_output_table_map.push(quote! { (#short, #i) });
        }

        flag_str_to_output_table_map.push(quote! { (#long_name, #i) });
    }
    flag_str_to_output_table_map
}

/// For each non-optional field, add an entry to the `argh::MissingRequirements`.
fn append_missing_requirements<'a>(
    // missing_requirements_ident
    mri: &syn::Ident,
    fields: &'a [StructField<'a>],
) -> impl Iterator<Item = TokenStream> + 'a {
    let mri = mri.clone();
    fields.iter().filter(|f| f.optionality.is_required()).map(move |field| {
        let field_name = field.name;
        match field.kind {
            FieldKind::Switch => unreachable!("switches are always optional"),
            FieldKind::Positional => {
                let name = field.arg_name();
                quote! {
                    if #field_name.slot.is_none() {
                        #mri.missing_positional_arg(#name)
                    }
                }
            }
            FieldKind::Option => {
                let name = field.long_name.as_ref().expect("options always have a long name");
                quote! {
                    if #field_name.slot.is_none() {
                        #mri.missing_option(#name)
                    }
                }
            }
            FieldKind::SubCommand => {
                let ty = field.ty_without_wrapper;
                quote! {
                    if #field_name.is_none() {
                        #mri.missing_subcommands(
                            <#ty as argh::SubCommands>::COMMANDS,
                        )
                    }
                }
            }
        }
    })
}

/// Require that a type can be a `switch`.
/// Throws an error for all types except booleans and integers
fn ty_expect_switch(errors: &Errors, ty: &syn::Type) -> bool {
    fn ty_can_be_switch(ty: &syn::Type) -> bool {
        if let syn::Type::Path(path) = ty {
            if path.qself.is_some() {
                return false;
            }
            if path.path.segments.len() != 1 {
                return false;
            }
            let ident = &path.path.segments[0].ident;
            ["bool", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"]
                .iter()
                .any(|path| ident == path)
        } else {
            false
        }
    }

    let res = ty_can_be_switch(ty);
    if !res {
        errors.err(ty, "switches must be of type `bool` or integer type");
    }
    res
}

/// Returns `Some(T)` if a type is `wrapper_name<T>` for any `wrapper_name` in `wrapper_names`.
fn ty_inner<'a>(wrapper_names: &[&str], ty: &'a syn::Type) -> Option<&'a syn::Type> {
    if let syn::Type::Path(path) = ty {
        if path.qself.is_some() {
            return None;
        }
        // Since we only check the last path segment, it isn't necessarily the case that
        // we're referring to `std::vec::Vec` or `std::option::Option`, but there isn't
        // a fool proof way to check these since name resolution happens after macro expansion,
        // so this is likely "good enough" (so long as people don't have their own types called
        // `Option` or `Vec` that take one generic parameter they're looking to parse).
        let last_segment = path.path.segments.last()?;
        if !wrapper_names.iter().any(|name| last_segment.ident == *name) {
            return None;
        }
        if let syn::PathArguments::AngleBracketed(gen_args) = &last_segment.arguments {
            let generic_arg = gen_args.args.first()?;
            if let syn::GenericArgument::Type(ty) = &generic_arg {
                return Some(ty);
            }
        }
    }
    None
}

/// Implements `FromArgs` and `SubCommands` for a `#![derive(FromArgs)]` enum.
fn impl_from_args_enum(
    errors: &Errors,
    name: &syn::Ident,
    type_attrs: &TypeAttrs,
    de: &syn::DataEnum,
) -> TokenStream {
    parse_attrs::check_enum_type_attrs(errors, type_attrs, &de.enum_token.span);

    // An enum variant like `<name>(<ty>)`
    struct SubCommandVariant<'a> {
        name: &'a syn::Ident,
        ty: &'a syn::Type,
    }

    let variants: Vec<SubCommandVariant<'_>> = de
        .variants
        .iter()
        .filter_map(|variant| {
            parse_attrs::check_enum_variant_attrs(errors, variant);
            let name = &variant.ident;
            let ty = enum_only_single_field_unnamed_variants(errors, &variant.fields)?;
            Some(SubCommandVariant { name, ty })
        })
        .collect();

    let name_repeating = std::iter::repeat(name.clone());
    let variant_ty = variants.iter().map(|x| x.ty).collect::<Vec<_>>();
    let variant_names = variants.iter().map(|x| x.name).collect::<Vec<_>>();

    quote! {
        impl argh::FromArgs for #name {
            fn from_args(command_name: &[&str], args: &[&str])
                -> std::result::Result<Self, argh::EarlyExit>
            {
                let subcommand_name = *command_name.last().expect("no subcommand name");
                #(
                    if subcommand_name == <#variant_ty as argh::SubCommand>::COMMAND.name {
                        return Ok(#name_repeating::#variant_names(
                            <#variant_ty as argh::FromArgs>::from_args(command_name, args)?
                        ));
                    }
                )*
                unreachable!("no subcommand matched")
            }

            fn redact_arg_values(command_name: &[&str], args: &[&str]) -> std::result::Result<Vec<String>, argh::EarlyExit> {
                let subcommand_name = *command_name.last().expect("no subcommand name");
                #(
                    if subcommand_name == <#variant_ty as argh::SubCommand>::COMMAND.name {
                        return <#variant_ty as argh::FromArgs>::redact_arg_values(command_name, args);
                    }
                )*
                unreachable!("no subcommand matched")
            }
        }

        impl argh::SubCommands for #name {
            const COMMANDS: &'static [&'static argh::CommandInfo] = &[#(
                <#variant_ty as argh::SubCommand>::COMMAND,
            )*];
        }
    }
}

/// Returns `Some(Bar)` if the field is a single-field unnamed variant like `Foo(Bar)`.
/// Otherwise, generates an error.
fn enum_only_single_field_unnamed_variants<'a>(
    errors: &Errors,
    variant_fields: &'a syn::Fields,
) -> Option<&'a syn::Type> {
    macro_rules! with_enum_suggestion {
        ($help_text:literal) => {
            concat!(
                $help_text,
                "\nInstead, use a variant with a single unnamed field for each subcommand:\n",
                "    enum MyCommandEnum {\n",
                "        SubCommandOne(SubCommandOne),\n",
                "        SubCommandTwo(SubCommandTwo),\n",
                "    }",
            )
        };
    }

    match variant_fields {
        syn::Fields::Named(fields) => {
            errors.err(
                fields,
                with_enum_suggestion!(
                    "`#![derive(FromArgs)]` `enum`s do not support variants with named fields."
                ),
            );
            None
        }
        syn::Fields::Unit => {
            errors.err(
                variant_fields,
                with_enum_suggestion!(
                    "`#![derive(FromArgs)]` does not support `enum`s with no variants."
                ),
            );
            None
        }
        syn::Fields::Unnamed(fields) => {
            if fields.unnamed.len() != 1 {
                errors.err(
                    fields,
                    with_enum_suggestion!(
                        "`#![derive(FromArgs)]` `enum` variants must only contain one field."
                    ),
                );
                None
            } else {
                // `unwrap` is okay because of the length check above.
                let first_field = fields.unnamed.first().unwrap();
                Some(&first_field.ty)
            }
        }
    }
}
