@@ -29,6 +29,7 @@ class BaseGenerator(metaclass=ABCMeta):
2929
3030 def __init__ (self , template : str ) -> None :
3131 self ._template = template
32+ self ._env : Environment | None = None
3233
3334 @abstractmethod
3435 def supported_nodes (self ) -> list [type ]:
@@ -49,30 +50,36 @@ def get_import_directives(self, tree: SyntaxTree) -> list[str]:
4950 """Return language-specific import directives. Override in subclasses."""
5051 return []
5152
53+ def _get_environment (self , tree : SyntaxTree ) -> Environment :
54+ if self ._env is None :
55+ env = Environment (loader = PackageLoader ('flatdata.generator' , 'templates' ), lstrip_blocks = True ,
56+ trim_blocks = True , autoescape = False , extensions = [RaiseExtension ])
57+ env .filters ['is_archive' ] = lambda n : isinstance (n , Archive )
58+ env .filters ['is_instance' ] = lambda n : isinstance (n , Instance )
59+ env .filters ['is_raw_data' ] = lambda n : isinstance (n , RawData )
60+ env .filters ['is_archive_resource' ] = lambda n : isinstance (
61+ n , ArchiveResource )
62+ env .filters ['is_structure' ] = lambda n : isinstance (n , Structure )
63+ env .filters ['is_enumeration_reference' ] = lambda n : isinstance (n , EnumerationReference )
64+ env .filters ['is_enumeration' ] = lambda n : isinstance (n , Enumeration )
65+ env .filters ['is_constant' ] = lambda n : isinstance (n , Constant )
66+ env .filters ['is_namespace' ] = lambda n : isinstance (n , Namespace )
67+ env .filters ['is_resource' ] = lambda n : isinstance (n , ResourceBase )
68+ env .filters ['is_bound_resource' ] = lambda n : isinstance (
69+ n , BoundResource )
70+ env .filters ['is_vector' ] = lambda n : isinstance (n , Vector )
71+ env .filters ['is_multivector' ] = lambda n : isinstance (n , Multivector )
72+ env .filters ['is_multivector_index' ] = lambda n : (isinstance (
73+ n , Structure ) and "_builtin.multivector" in SyntaxTree .namespace_path (n ))
74+ env .filters ['namespaces' ] = SyntaxTree .namespaces
75+ env .filters ['not_auto_generated' ] = lambda n : [ x for x in n if not x .auto_generated ]
76+ self ._populate_environment (env , tree )
77+ self ._env = env
78+ return self ._env
79+
5280 def render (self , tree : SyntaxTree ) -> str :
5381 """Generate the language implementation from the AST"""
54- env = Environment (loader = PackageLoader ('flatdata.generator' , 'templates' ), lstrip_blocks = True ,
55- trim_blocks = True , autoescape = False , extensions = [RaiseExtension ])
56- env .filters ['is_archive' ] = lambda n : isinstance (n , Archive )
57- env .filters ['is_instance' ] = lambda n : isinstance (n , Instance )
58- env .filters ['is_raw_data' ] = lambda n : isinstance (n , RawData )
59- env .filters ['is_archive_resource' ] = lambda n : isinstance (
60- n , ArchiveResource )
61- env .filters ['is_structure' ] = lambda n : isinstance (n , Structure )
62- env .filters ['is_enumeration_reference' ] = lambda n : isinstance (n , EnumerationReference )
63- env .filters ['is_enumeration' ] = lambda n : isinstance (n , Enumeration )
64- env .filters ['is_constant' ] = lambda n : isinstance (n , Constant )
65- env .filters ['is_namespace' ] = lambda n : isinstance (n , Namespace )
66- env .filters ['is_resource' ] = lambda n : isinstance (n , ResourceBase )
67- env .filters ['is_bound_resource' ] = lambda n : isinstance (
68- n , BoundResource )
69- env .filters ['is_vector' ] = lambda n : isinstance (n , Vector )
70- env .filters ['is_multivector' ] = lambda n : isinstance (n , Multivector )
71- env .filters ['is_multivector_index' ] = lambda n : (isinstance (
72- n , Structure ) and "_builtin.multivector" in SyntaxTree .namespace_path (n ))
73- env .filters ['namespaces' ] = SyntaxTree .namespaces
74- env .filters ['not_auto_generated' ] = lambda n : [ x for x in n if not x .auto_generated ]
75- self ._populate_environment (env , tree )
82+ env = self ._get_environment (tree )
7683 template = env .get_template (self ._template )
7784
7885 flatdata_nodes = [n for n , _ in DfsTraversal (tree ).dependency_order () if
0 commit comments