Source code for linkml.generators.common.lifecycle

"""
Lifestyle methods mixin
"""

from typing import Iterable, TypeVar

from linkml_runtime import SchemaView
from linkml_runtime.linkml_model.meta import (
    ClassDefinition,
    EnumDefinition,
    SchemaDefinition,
    SlotDefinition,
    TypeDefinition,
)

from linkml.generators.common.build import ClassResult, RangeResult, SchemaResult, SlotResult, TypeResult
from linkml.generators.common.template import TemplateModel

TSchema = TypeVar("TSchema", bound=SchemaResult)
TClass = TypeVar("TClass", bound=ClassResult)
TSlot = TypeVar("TSlot", bound=SlotResult)
TRange = TypeVar("TRange", bound=RangeResult)
TType = TypeVar("TType", bound=TypeResult)
TEnum = TypeVar("TEnum", bound=EnumDefinition)
TTemplate = TypeVar("TTemplate", bound=TemplateModel)


[docs]class LifecycleMixin: """ Mixin class for implementing lifecycle methods to modify the generation process without needing messy overrides and tiptoeing around parent generator classes. Not all classes that inherit from the mixin will be able to implement all of the lifecycle methods. The generator class should make it clear which methods are supported in its documentation - no programmatic checking for lifecycle method support is available on first implementation. Generators should **not** define any of the lifecycle methods themselves - the purpose is to allow downstream modification of the generation process with clear entrypoints and without needing to copy/paste code from the generator/call ``super()`` methods - if the Generator is also using the lifecycle method, the point of the mixin is lost. The order that these methods are called may vary in different generators, but in general, if slots are generated hierarchically within classes as in the pydantic generator... * :meth:`.before_generate_schema` * :meth:`.before_generate_classes` * :meth:`.before_generate_class` * :meth:`.before_generate_slots` * :meth:`.before_generate_slot` * :meth:`.after_generate_slot` * :meth:`.after_generate_slots` * :meth:`.after_generate_class` * :meth:`.after_generate_classes` * :meth:`.after_generate_schema` * :meth:`.before_render_template` * :meth:`.after_render_template` (Add other examples of ordering from other generators as implemented) Each method should receive a :class:`.SchemaView` to get perspective on the current schema being built. The ``before_`` methods should receive and return a single or list of ``Definitions`` and the ``after_`` methods should receive and return a single or list of the appropriate :class:`.BuildResult` type. """ def before_generate_schema(self, schema: SchemaDefinition, sv: SchemaView) -> SchemaDefinition: return schema def after_generate_schema(self, schema: TSchema, sv: SchemaView) -> TSchema: return schema def before_generate_class(self, cls: ClassDefinition, sv: SchemaView) -> ClassDefinition: return cls def after_generate_class(self, cls: TClass, sv: SchemaView) -> TClass: return cls def before_generate_classes(self, cls: Iterable[ClassDefinition], sv: SchemaView) -> Iterable[ClassDefinition]: return cls def after_generate_classes(self, cls: Iterable[TClass], sv: SchemaView) -> Iterable[TClass]: return cls def before_generate_slot(self, slot: SlotDefinition, sv: SchemaView) -> SlotDefinition: return slot def after_generate_slot(self, slot: TSlot, sv: SchemaView) -> TSlot: return slot def before_generate_slots(self, slot: Iterable[SlotDefinition], sv: SchemaView) -> Iterable[SlotDefinition]: return slot def after_generate_slots(self, slot: Iterable[TSlot], sv: SchemaView) -> Iterable[TSlot]: return slot def before_generate_type(self, typ: TypeDefinition, sv: SchemaView) -> TypeDefinition: return typ def after_generate_type(self, typ: TType, sv: SchemaView) -> TType: return typ def before_generate_types(self, typ: Iterable[TypeDefinition], sv: SchemaView) -> Iterable[TypeDefinition]: return typ def after_generate_types(self, typ: Iterable[TType], sv: SchemaView) -> Iterable[TType]: return typ def before_generate_enum(self, enum: EnumDefinition, sv: SchemaView) -> EnumDefinition: return enum def after_generate_enum(self, enum: TEnum, sv: SchemaView) -> TEnum: return enum def before_generate_enums(self, enum: Iterable[EnumDefinition], sv: SchemaView) -> Iterable[EnumDefinition]: return enum def after_generate_enums(self, enum: Iterable[TEnum], sv: SchemaView) -> Iterable[TEnum]: return enum def before_render_template(self, template: TTemplate, sv: SchemaView) -> TTemplate: return template def after_render_template(self, template: str, sv: SchemaView) -> str: return template