add metaprogramming to generate metamodel