extern crate proc_macro;

use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{
    parse_macro_input, Data, DeriveInput, Fields, Type, LitInt, ItemImpl,
};

fn get_default_value(ty: &Type) -> proc_macro2::TokenStream {
    let ty_str = ty.to_token_stream().to_string();
    match ty_str.as_str() {
        "bool" => quote! { false },
        "u8" | "u16" | "u32" | "u64" | "u128" | "usize" |
        "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => quote! { 0 },
        "String" => quote! { String::from("") },
        "VecBool" | "VecU8" | "VecU16" | "VecU32" | "VecU64" | "VecU128" | "VecUsize" |
        "VecI8" | "VecI16" | "VecI32" | "VecI64" | "VecI128" | "VecIsize" | "VecStr" => {
            quote! { #ty::new() }
        }
        _ => quote! { #ty::new() }
    }
}

#[proc_macro_derive(ReflectInfo, attributes(primary_key, auto_increment, not_null, varchar, reflect_method, reflect_methods_const))]
pub fn derive_reflect_info(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);

    let struct_name = &input.ident;

    // 收集 reflect_method 属性（旧方式）
    let reflect_methods: Vec<String> = input.attrs.iter()
        .filter(|attr| attr.path().is_ident("reflect_method"))
        .filter_map(|attr| {
            attr.parse_args::<syn::LitStr>().ok().map(|lit| lit.value())
        })
        .collect();

    // 检查是否有 reflect_methods_const 属性（新方式）
    let reflect_methods_const: Option<String> = input.attrs.iter()
        .find(|attr| attr.path().is_ident("reflect_methods_const"))
        .and_then(|attr| attr.parse_args::<syn::LitStr>().ok().map(|lit| lit.value()));

    let get_methods_impl = if let Some(const_name) = &reflect_methods_const {
        let const_ident = syn::Ident::new(const_name, proc_macro2::Span::call_site());
        quote! {
            fn get_methods(&self) -> Vec<&'static str> {
                #const_ident.to_vec()
            }
        }
    } else {
        quote! {
            fn get_methods(&self) -> Vec<&'static str> {
                vec![#(#reflect_methods,)*]
            }
        }
    };

    let data = match input.data {
        Data::Struct(data) => data,
        _ => panic!("ReflectInfo can only be derived for structs"),
    };

    let fields = match data.fields {
        Fields::Named(fields) => fields.named,
        Fields::Unnamed(_) => panic!("ReflectInfo requires named fields"),
        Fields::Unit => panic!("ReflectInfo requires named fields"),
    };

    let field_inits = fields.iter().map(|f| {
        let name = f.ident.as_ref().unwrap();
        let ty = &f.ty;
        let default = get_default_value(ty);
        quote! { #name: #default }
    });

    let fields_map = fields.iter().map(|f| {
        let name = f.ident.as_ref().unwrap();
        let ty = &f.ty;
        quote! { fields.insert(stringify!(#name), stringify!(#ty)); }
    });

    // 收集字段属性信息
    let mut primary_key_checks = Vec::new();
    let mut auto_increment_checks = Vec::new();
    let mut not_null_checks = Vec::new();
    let mut varchar_checks = Vec::new();
    let mut varchar_len_checks = Vec::new();

    for f in fields.iter() {
        let name = f.ident.as_ref().unwrap();
        
        // 检查 primary_key 属性
        let has_primary_key = f.attrs.iter().any(|attr| {
            attr.path().is_ident("primary_key")
        });
        primary_key_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #has_primary_key;
            }
        });

        // 检查 auto_increment 属性
        let has_auto_increment = f.attrs.iter().any(|attr| {
            attr.path().is_ident("auto_increment")
        });
        auto_increment_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #has_auto_increment;
            }
        });

        // 检查 not_null 属性
        let has_not_null = f.attrs.iter().any(|attr| {
            attr.path().is_ident("not_null")
        });
        not_null_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #has_not_null;
            }
        });

        // 检查 varchar 属性
        let (is_varchar, varchar_len) = f.attrs.iter()
            .find(|attr| attr.path().is_ident("varchar"))
            .map_or((false, quote! { None }), |attr| {
                // 尝试解析 varchar(n) 参数
                if let Ok(len) = attr.parse_args::<LitInt>() {
                    let len_val: u16 = len.base10_parse().unwrap_or(255);
                    (true, quote! { Some(#len_val) })
                } else {
                    (true, quote! { Some(255) })
                }
            });
        
        varchar_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #is_varchar;
            }
        });

        varchar_len_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #varchar_len;
            }
        });
    }

    // 收集 index 相关检查
    let mut is_index_checks = Vec::new();
    let mut get_index_keys_checks = Vec::new();
    for f in fields.iter() {
        let name = f.ident.as_ref().unwrap();
        let name_str = name.to_string();
        let (is_index, index_keys) = if name_str.starts_with("index_") {
            let rest = &name_str["index_".len()..];
            if !rest.is_empty() {
                let keys: Vec<&str> = rest.split('_').collect();
                
                (true, quote! {
                    {
                        let vec = vec![
                            #(#keys,)*
                        ];
                        Some(vec)
                    }
                })
            } else {
                (false, quote! { None })
            }
        } else {
            (false, quote! { None })
        };

        is_index_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #is_index;
            }
        });

        get_index_keys_checks.push(quote! {
            if field_name == stringify!(#name) {
                return #index_keys;
            }
        });
    }

    let mut bool_setters = Vec::new();
    let mut bool_getters = Vec::new();
    let mut u8_setters = Vec::new();
    let mut u8_getters = Vec::new();
    let mut u16_setters = Vec::new();
    let mut u16_getters = Vec::new();
    let mut u32_setters = Vec::new();
    let mut u32_getters = Vec::new();
    let mut u64_setters = Vec::new();
    let mut u64_getters = Vec::new();
    let mut u128_setters = Vec::new();
    let mut u128_getters = Vec::new();
    let mut usize_setters = Vec::new();
    let mut usize_getters = Vec::new();
    let mut i8_setters = Vec::new();
    let mut i8_getters = Vec::new();
    let mut i16_setters = Vec::new();
    let mut i16_getters = Vec::new();
    let mut i32_setters = Vec::new();
    let mut i32_getters = Vec::new();
    let mut i64_setters = Vec::new();
    let mut i64_getters = Vec::new();
    let mut i128_setters = Vec::new();
    let mut i128_getters = Vec::new();
    let mut isize_setters = Vec::new();
    let mut isize_getters = Vec::new();
    let mut str_setters = Vec::new();
    let mut str_getters = Vec::new();
    let mut vec_bool_setters = Vec::new();
    let mut vec_bool_getters = Vec::new();
    let mut vec_u8_setters = Vec::new();
    let mut vec_u8_getters = Vec::new();
    let mut vec_u16_setters = Vec::new();
    let mut vec_u16_getters = Vec::new();
    let mut vec_u32_setters = Vec::new();
    let mut vec_u32_getters = Vec::new();
    let mut vec_u64_setters = Vec::new();
    let mut vec_u64_getters = Vec::new();
    let mut vec_u128_setters = Vec::new();
    let mut vec_u128_getters = Vec::new();
    let mut vec_usize_setters = Vec::new();
    let mut vec_usize_getters = Vec::new();
    let mut vec_i8_setters = Vec::new();
    let mut vec_i8_getters = Vec::new();
    let mut vec_i16_setters = Vec::new();
    let mut vec_i16_getters = Vec::new();
    let mut vec_i32_setters = Vec::new();
    let mut vec_i32_getters = Vec::new();
    let mut vec_i64_setters = Vec::new();
    let mut vec_i64_getters = Vec::new();
    let mut vec_i128_setters = Vec::new();
    let mut vec_i128_getters = Vec::new();
    let mut vec_isize_setters = Vec::new();
    let mut vec_isize_getters = Vec::new();
    let mut vec_str_setters = Vec::new();
    let mut vec_str_getters = Vec::new();
    let mut obj_getters = Vec::new();
    let mut obj_getters_mut = Vec::new();

    for f in fields.iter() {
        let name = f.ident.as_ref().unwrap();
        let ty = &f.ty;
        let ty_str = ty.to_token_stream().to_string();

        match ty_str.as_str() {
            "bool" => {
                bool_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                bool_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "u8" => {
                u8_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                u8_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "u16" => {
                u16_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                u16_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "u32" => {
                u32_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                u32_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "u64" => {
                u64_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                u64_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "u128" => {
                u128_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                u128_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "usize" => {
                usize_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                usize_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "i8" => {
                i8_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                i8_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "i16" => {
                i16_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                i16_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "i32" => {
                i32_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                i32_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "i64" => {
                i64_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                i64_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "i128" => {
                i128_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                i128_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "isize" => {
                isize_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value;
                        return true;
                    }
                });
                isize_getters.push(quote! {
                    if name == stringify!(#name) {
                        return self.#name;
                    }
                });
            }
            "String" => {
                str_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                str_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecBool" => {
                vec_bool_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_bool_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecU8" => {
                vec_u8_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_u8_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecU16" => {
                vec_u16_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_u16_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecU32" => {
                vec_u32_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_u32_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecU64" => {
                vec_u64_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_u64_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecU128" => {
                vec_u128_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_u128_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecUsize" => {
                vec_usize_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_usize_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecI8" => {
                vec_i8_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_i8_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecI16" => {
                vec_i16_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_i16_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecI32" => {
                vec_i32_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_i32_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecI64" => {
                vec_i64_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_i64_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecI128" => {
                vec_i128_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_i128_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecIsize" => {
                vec_isize_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_isize_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            "VecStr" => {
                vec_str_setters.push(quote! {
                    if name == stringify!(#name) {
                        self.#name = value.clone();
                        return true;
                    }
                });
                vec_str_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
            }
            _ => {
                obj_getters.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&self.#name);
                    }
                });
                obj_getters_mut.push(quote! {
                    if name == stringify!(#name) {
                        return Some(&mut self.#name);
                    }
                });
            }
        }
    }

    let expanded = quote! {
        impl #struct_name {
            pub fn new() -> #struct_name {
                #struct_name {
                    #(
                        #field_inits,
                    )*
                }
            }
        }

        impl reflect_info::IReflect for #struct_name {
            fn get_name(&self) -> String {
                String::from(stringify!(#struct_name))
            }

            fn get_fields(&self) -> linked_hash_map::LinkedHashMap<&'static str, &'static str> {
                let mut fields = linked_hash_map::LinkedHashMap::new();
                #(
                    #fields_map
                )*
                fields
            }

            #get_methods_impl

            fn is_primary_key(&self, field_name: &str) -> bool {
                #(#primary_key_checks)*
                false
            }

            fn is_auto_increment(&self, field_name: &str) -> bool {
                #(#auto_increment_checks)*
                false
            }

            fn is_not_null(&self, field_name: &str) -> bool {
                #(#not_null_checks)*
                false
            }

            fn is_varchar(&self, field_name: &str) -> bool {
                #(#varchar_checks)*
                false
            }

            fn get_varchar_len(&self, field_name: &str) -> Option<u16> {
                #(#varchar_len_checks)*
                None
            }

            fn is_index(&self, field_name: &str) -> bool {
                #(#is_index_checks)*
                false
            }

            fn get_index_keys(&self, field_name: &str) -> Option<Vec<&'static str>> {
                #(#get_index_keys_checks)*
                None
            }

            fn set_bool_value(&mut self, name: &str, value: bool) -> bool {
                #(#bool_setters)*
                false
            }
            fn get_bool_value(&self, name: &str) -> bool {
                #(#bool_getters)*
                false
            }

            fn set_u8_value(&mut self, name: &str, value: u8) -> bool {
                #(#u8_setters)*
                false
            }
            fn get_u8_value(&self, name: &str) -> u8 {
                #(#u8_getters)*
                0
            }

            fn set_u16_value(&mut self, name: &str, value: u16) -> bool {
                #(#u16_setters)*
                false
            }
            fn get_u16_value(&self, name: &str) -> u16 {
                #(#u16_getters)*
                0
            }

            fn set_u32_value(&mut self, name: &str, value: u32) -> bool {
                #(#u32_setters)*
                false
            }
            fn get_u32_value(&self, name: &str) -> u32 {
                #(#u32_getters)*
                0
            }

            fn set_u64_value(&mut self, name: &str, value: u64) -> bool {
                #(#u64_setters)*
                false
            }
            fn get_u64_value(&self, name: &str) -> u64 {
                #(#u64_getters)*
                0
            }

            fn set_u128_value(&mut self, name: &str, value: u128) -> bool {
                #(#u128_setters)*
                false
            }
            fn get_u128_value(&self, name: &str) -> u128 {
                #(#u128_getters)*
                0
            }

            fn set_usize_value(&mut self, name: &str, value: usize) -> bool {
                #(#usize_setters)*
                false
            }
            fn get_usize_value(&self, name: &str) -> usize {
                #(#usize_getters)*
                0
            }

            fn set_i8_value(&mut self, name: &str, value: i8) -> bool {
                #(#i8_setters)*
                false
            }
            fn get_i8_value(&self, name: &str) -> i8 {
                #(#i8_getters)*
                0
            }

            fn set_i16_value(&mut self, name: &str, value: i16) -> bool {
                #(#i16_setters)*
                false
            }
            fn get_i16_value(&self, name: &str) -> i16 {
                #(#i16_getters)*
                0
            }

            fn set_i32_value(&mut self, name: &str, value: i32) -> bool {
                #(#i32_setters)*
                false
            }
            fn get_i32_value(&self, name: &str) -> i32 {
                #(#i32_getters)*
                0
            }

            fn set_i64_value(&mut self, name: &str, value: i64) -> bool {
                #(#i64_setters)*
                false
            }
            fn get_i64_value(&self, name: &str) -> i64 {
                #(#i64_getters)*
                0
            }

            fn set_i128_value(&mut self, name: &str, value: i128) -> bool {
                #(#i128_setters)*
                false
            }
            fn get_i128_value(&self, name: &str) -> i128 {
                #(#i128_getters)*
                0
            }

            fn set_isize_value(&mut self, name: &str, value: isize) -> bool {
                #(#isize_setters)*
                false
            }
            fn get_isize_value(&self, name: &str) -> isize {
                #(#isize_getters)*
                0
            }

            fn set_str_value(&mut self, name: &str, value: String) -> bool {
                #(#str_setters)*
                false
            }
            fn get_str_value(&self, name: &str) -> Option<&String> {
                #(#str_getters)*
                None
            }

            fn set_vec_bool_value(&mut self, name: &str, value: reflect_info::VecBool) -> bool {
                #(#vec_bool_setters)*
                false
            }
            fn get_vec_bool_value(&self, name: &str) -> Option<&reflect_info::VecBool> {
                #(#vec_bool_getters)*
                None
            }

            fn set_vec_u8_value(&mut self, name: &str, value: reflect_info::VecU8) -> bool {
                #(#vec_u8_setters)*
                false
            }
            fn get_vec_u8_value(&self, name: &str) -> Option<&reflect_info::VecU8> {
                #(#vec_u8_getters)*
                None
            }

            fn set_vec_u16_value(&mut self, name: &str, value: reflect_info::VecU16) -> bool {
                #(#vec_u16_setters)*
                false
            }
            fn get_vec_u16_value(&self, name: &str) -> Option<&reflect_info::VecU16> {
                #(#vec_u16_getters)*
                None
            }

            fn set_vec_u32_value(&mut self, name: &str, value: reflect_info::VecU32) -> bool {
                #(#vec_u32_setters)*
                false
            }
            fn get_vec_u32_value(&self, name: &str) -> Option<&reflect_info::VecU32> {
                #(#vec_u32_getters)*
                None
            }

            fn set_vec_u64_value(&mut self, name: &str, value: reflect_info::VecU64) -> bool {
                #(#vec_u64_setters)*
                false
            }
            fn get_vec_u64_value(&self, name: &str) -> Option<&reflect_info::VecU64> {
                #(#vec_u64_getters)*
                None
            }

            fn set_vec_u128_value(&mut self, name: &str, value: reflect_info::VecU128) -> bool {
                #(#vec_u128_setters)*
                false
            }
            fn get_vec_u128_value(&self, name: &str) -> Option<&reflect_info::VecU128> {
                #(#vec_u128_getters)*
                None
            }

            fn set_vec_usize_value(&mut self, name: &str, value: reflect_info::VecUsize) -> bool {
                #(#vec_usize_setters)*
                false
            }
            fn get_vec_usize_value(&self, name: &str) -> Option<&reflect_info::VecUsize> {
                #(#vec_usize_getters)*
                None
            }

            fn set_vec_i8_value(&mut self, name: &str, value: reflect_info::VecI8) -> bool {
                #(#vec_i8_setters)*
                false
            }
            fn get_vec_i8_value(&self, name: &str) -> Option<&reflect_info::VecI8> {
                #(#vec_i8_getters)*
                None
            }

            fn set_vec_i16_value(&mut self, name: &str, value: reflect_info::VecI16) -> bool {
                #(#vec_i16_setters)*
                false
            }
            fn get_vec_i16_value(&self, name: &str) -> Option<&reflect_info::VecI16> {
                #(#vec_i16_getters)*
                None
            }

            fn set_vec_i32_value(&mut self, name: &str, value: reflect_info::VecI32) -> bool {
                #(#vec_i32_setters)*
                false
            }
            fn get_vec_i32_value(&self, name: &str) -> Option<&reflect_info::VecI32> {
                #(#vec_i32_getters)*
                None
            }

            fn set_vec_i64_value(&mut self, name: &str, value: reflect_info::VecI64) -> bool {
                #(#vec_i64_setters)*
                false
            }
            fn get_vec_i64_value(&self, name: &str) -> Option<&reflect_info::VecI64> {
                #(#vec_i64_getters)*
                None
            }

            fn set_vec_i128_value(&mut self, name: &str, value: reflect_info::VecI128) -> bool {
                #(#vec_i128_setters)*
                false
            }
            fn get_vec_i128_value(&self, name: &str) -> Option<&reflect_info::VecI128> {
                #(#vec_i128_getters)*
                None
            }

            fn set_vec_isize_value(&mut self, name: &str, value: reflect_info::VecIsize) -> bool {
                #(#vec_isize_setters)*
                false
            }
            fn get_vec_isize_value(&self, name: &str) -> Option<&reflect_info::VecIsize> {
                #(#vec_isize_getters)*
                None
            }

            fn set_vec_str_value(&mut self, name: &str, value: reflect_info::VecStr) -> bool {
                #(#vec_str_setters)*
                false
            }
            fn get_vec_str_value(&self, name: &str) -> Option<&reflect_info::VecStr> {
                #(#vec_str_getters)*
                None
            }

            fn get_object_value(&self, name: &str) -> Option<&dyn reflect_info::IReflect> {
                #(#obj_getters)*
                None
            }
            fn get_object_value_mut(&mut self, name: &str) -> Option<&mut dyn reflect_info::IReflect> {
                #(#obj_getters_mut)*
                None
            }
        }
    };

    TokenStream::from(expanded)
}

#[proc_macro_attribute]
pub fn reflect_methods(_attr: TokenStream, input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemImpl);

    let self_ty = match &*input.self_ty {
        syn::Type::Path(path) => &path.path.segments.last().unwrap().ident,
        _ => panic!("reflect_methods only supports struct impls"),
    };

    let method_names: Vec<&syn::Ident> = input.items.iter()
        .filter_map(|item| {
            if let syn::ImplItem::Fn(method) = item {
                Some(&method.sig.ident)
            } else {
                None
            }
        })
        .collect();

    let const_name = syn::Ident::new(&format!("_REFLECT_METHODS_{}", self_ty), self_ty.span());

    let expanded = quote! {
        #input

        #[allow(non_upper_case_globals)]
        pub const #const_name: &'static [&'static str] = &[#(stringify!(#method_names),)*];
    };

    TokenStream::from(expanded)
}