Generator Plugin¶
To register a generator plugin, register the pydjinni.generator
entry-point in the plugins pyproject.toml
:
Pydjinni will now automatically load the plugin, once it is installed.
Target¶
Bases: ABC
Abstract class for defining generation targets. A target combines multiple generators to one entity. E.g. to allow Java interop, both a Java and JNI generator are required.
generators
abstractmethod
property
¶
A list of generators related to the target. Typically, targets will have two generators:
- For the target (host) language
- For the glue-code required in C++ to interact with the host language
internal
property
¶
Whether a generator is an internal component that does not produce code.
This is used to flag the yaml
generator as not being a language target.
key
abstractmethod
property
¶
The name of the target. Will be used by the API/CLI for selecting the target.
supported_deriving
property
¶
Record derivings that are supported by the target language. For documentation purposes only.
Generator¶
Bases: ABC
Abstract class for defining generators. Each generator can utilize one or more Marshal classes, specified as generic arguments.
config_model
abstractmethod
property
¶
The Pydantic model that defines the configuration options for the generator.
The model will automatically be registered in the system and is then available in the documentation and as part of the JSON-Schema for the configuration file.
external_type_model
property
¶
The Pydantic model of the external type specification for the generator. The model should contain all information that is required to reference and use an external type in the generated code.
The model will automatically be registered in the system and is then available in the documentation and as part of the JSON-Schema for external types.
external_types
property
¶
A dictionary of all builtin types that are supported by the generator. If the list is incomplete, an error is thrown when the user tries to use an unsupported type in a project that uses the generator.
A complete list of all builtin types can be found in pydjinni/generator/external_types.py
filters
property
¶
Jinja2 filter functions that are required in the generators Jinja templates
header_path
property
¶
The path where generated header files should be written.
The default implementation expects the generators config model to contain a field out
that is either a Path
or of type OutPaths
.
Override this if the generators config doesn't match with those expectations.
key
abstractmethod
property
¶
The name of the generator. Will be used as configuration key and for importing/exporting external types.
Typically, a target will have one generator with the same name (key) as the target. If additional glue code in C++ is provided, this will usually require a separate generator with a distinct name.
marshal_models
property
¶
A mapping of AST types to the marshalling model required by the generator. For each type in the AST, the generator searches for a matching marshalling model in this dictionary. If no marshalling model is found, an error will be thrown suggesting that the given AST type is not supported by the generator.
The generator will search for a matching marshalling model by traversing the type hierarchy of the AST type until a matching marshalling model is found.
A marshalling model must be a Pydantic model with two fields:
- decl
for the type of field declaration and
- config
for the generator configuration
All marshalling must happen in methods decorated as @cached_property
, where the declaration and the
configuration is used to derive information needed by the generator.
Type marshalling properties must at least contain a property for each field in the given external type model.
Every property that should be exported as part of the external type YAML definition must be decorated with
@computed_field
.
source_path
property
¶
The path where generated source files should be written.
The default implementation expects the generators config model to contain a field out
that is either a Path
or of type OutPaths
.
Override this if the generators config doesn't match with those expectations.
support_lib_commons
property
¶
Whether the code generated by this generator depends on the common support lib code provided by pydjinni.
tests
property
¶
Jinja2 test functions that are required in the generators Jinja templates
writes_header
property
¶
Whether the generator will generate header files. This information is required for documentation purposes and for providing a valid JSON-Schema for the processed files report.
writes_source
property
¶
Whether the generator will generate source files. This information is required for documentation purposes and for providing a valid JSON-Schema for the processed files report.
GenerationException
¶
Bases: ApplicationException
Generation error
clean()
¶
purge all content from source and header output directories
generate(ast, copy_support_lib_sources=True)
¶
This method is initiated by the system to start code generation.
Iterates over all given type definitions and dynamically searches for a matching generator function.
A valid generator function must have the following signature, where <type>
is a lowercase representation of
the full type name, separated by _
instead of .
if the given type is a subclass:
If no direct match for the types class name can be found, the inheritance hierarchy is traversed until a match was found.
Examples:
def generate_interface(self, type_def: Interface)
will match for theInterface
type.def generate_base_type(self, type_def: BaseType)
will match for all types deriving fromBaseType
if no better match can be found.
This method may be overridden if the default dynamic detection behaviour doesn't fit the requirements.
generate_support_lib()
¶
Copies support lib files if they exist. Fails silently if no files can be found in the expected directories.
marshal(type_decls, field_decls)
¶
Attaches marshalling models to the provided type and field definitions.
Searches the provided marshalling model mappings for a matching marshalling model for each given type or field. If no direct match can be found, the inheritance hierarchy is traversed until a matching model is found.
Once a matching marshalling model was found, it is initialized and attached to the given type/field definition.
Note
During attachment of the marshalling models, no actual marshalling is happening. Only during rendering of the Jinja templates the marshalling model properties are evaluated.
The method may be overridden with custom marshalling logic if the default behaviour doesn't fit the requirements. But the outcome must always be a Pydantic model being attached to each given type and field declaration passed to the method!
write_header(template, filename=None, **kwargs)
¶
Method that must be used for any header file that is written by the generator.
Providing a filename is optional if a type definition is provided in the type_def
parameter. In this case the
filename can be derived from the marshalling model, given that a header
field is provided.
write_source(template, filename=None, **kwargs)
¶
Method that must be used for any source file that is written by the generator.
Providing a filename is optional if a type definition is provided in the type_def
parameter. In this case the
filename can be derived from the marshalling model, given that a source
field is provided.