
# Generated by OTF2 Template Engine

from builtins import filter
from collections import defaultdict, OrderedDict
from itertools import chain
from functools import wraps
from six import string_types

import _otf2

from . import definitions
from .error import TraceReaderError, TraceWriterError
from .enums import Undefined, GroupType
from .definitions import ClockProperties


def _use_doc_from(doc):
    def decorator(func):
        doc_str = "Returns the {} definition with matching arguments\n".format(doc.__name__)
        if isinstance(doc, definitions._RefDefinition):
            doc_str += "If there is no matching definition, one will be created.\n"
        doc_str += "\n"
        doc_str += doc.__doc__

        func.__doc__ = doc_str
        return func
    return decorator


class _Registry(object):
    def __init__(self, definition_registry, default_type=None):
        self._definition_registry = definition_registry
        self._default_type = default_type
        self._extra_callbacks = {}

    def _callback_gen(self, definition_type=None):
        if definition_type is None:
            definition_type = self._default_type

        def callback(definition_registry, *args):
            definition = definition_type._construct(definition_registry, *args)
            try:
                self._register(definition)
            except KeyError:
                raise TraceReaderError("Duplicate definition: {}".format(definition))
        self._extra_callbacks[definition_type] = callback
        return callback

    def create(self, *args, **kwargs):
        t = kwargs.pop('_type', self._default_type)
        obj = t(self, *args, **kwargs)
        self._register(obj)
        return obj


class _ListRegistry(_Registry):
    def __init__(self, definition_registry, default_type=None):
        self._elements = []
        super(_ListRegistry, self).__init__(definition_registry, default_type)

    def _register(self, obj):
        self._elements.append(obj)

    def __iter__(self):
        """ Do not try to add elements during iteration """
        for elem in self._elements:
            yield elem


class _RefRegistry(_Registry):
    """
    All objects recorded by this registry must have:
    - a ref (id) of type int as first constructor parameter.
      This must not be changed once an event with that ref is written in the trace
    - a name of type str as a second constructor parameter.
      If this is changed, the _elements_by_name must be updated
     """
    def __init__(self, definition_registry, undefined_ref, default_type=None):
        self._elements_by_key = dict()
        self._elements_by_ref = OrderedDict({undefined_ref.value: None})

        self._ref = -1
        self._extra_callbacks = dict()
        super(_RefRegistry, self).__init__(definition_registry, default_type)

    def _next_ref(self):
        self._ref += 1
        return self._ref

    def create(self, *args, **kwargs):
        ref = self._next_ref()
        return super(_RefRegistry, self).create(ref, *args, **kwargs)

    def get(self, *args, **kwargs):
        t = kwargs.pop('_type', self._default_type)
        key = t._new_key(self, *args, **kwargs)
        try:
            return self._elements_by_key[key]
        except KeyError:
            pass
        return self.create(*args, _type=t, **kwargs)

    def _register(self, obj):
        if obj._ref in self._elements_by_ref:
            raise KeyError("Trying to register definition with existing reference.")
        self._elements_by_key[obj._key] = obj
        self._elements_by_ref[obj._ref] = obj
        # Maybe redundant, don't care
        self._ref = max(self._ref, obj._ref)

    def __iter__(self):
        """ Do not try to add elements during iteration """
        for elem in self._elements_by_ref.values():
            # Skip the Undefined entry
            if elem is not None:
                yield elem

    def __getitem__(self, ref):
        return self._elements_by_ref[ref]

    def __contains__(self, item):
        return item._key in self._elements_by_key

    def __len__(self):
        return len(self._elements_by_ref) - 1


class _StringRegistry(_RefRegistry):
    """
    This is a special registry for strings.
    """
    def __init__(self, definition_registry):
        super(_StringRegistry, self).__init__(definition_registry, Undefined.STRING,
                                              definitions.String)

    def __getitem__(self, ref):
        if self._elements_by_ref[ref] is None:
            return None
        return self._elements_by_ref[ref].name

    def get_ref(self, name, writer=None):
        """
        Get a definition object, and write it in the writer if it was not yet created.
        This means, that all previously created definitions should already be written to the writer.
        Returns the ref of the definition for simplicity.
        """
        # Avoid converting unicode stuff to str with Python2
        # The low level interface will handle any basestring correctly
        if not isinstance(name, string_types):
            name = str(name)
        key = definitions.String._new_key(self, name)
        try:
            return self._elements_by_key[key]._ref
        except KeyError:
            pass
        obj = self.create(name, _type=definitions.String)
        if writer:
            obj.write(writer, self._definition_registry)
        return obj._ref


class DefinitionRegistry(object):
    """
        This class stores all definitions.
    """
    def __init__(self):
        self.clock_properties = None
        self._strings = _StringRegistry(self)
        self._metrics = _RefRegistry(self, Undefined.METRIC)
        self._comms = _RefRegistry(self, Undefined.COMM)
        self._io_files = _RefRegistry(self, Undefined.IO_FILE)
        self._io_paradigms = _RefRegistry(self, Undefined.IO_PARADIGM, definitions.IoParadigm)
        self._attributes = _RefRegistry(self, Undefined.ATTRIBUTE, definitions.Attribute)
        self._system_tree_nodes = _RefRegistry(self, Undefined.SYSTEM_TREE_NODE, definitions.SystemTreeNode)
        self._location_groups = _RefRegistry(self, Undefined.LOCATION_GROUP, definitions.LocationGroup)
        self._locations = _RefRegistry(self, Undefined.LOCATION, definitions.Location)
        self._regions = _RefRegistry(self, Undefined.REGION, definitions.Region)
        self._callsites = _RefRegistry(self, Undefined.CALLSITE, definitions.Callsite)
        self._callpaths = _RefRegistry(self, Undefined.CALLPATH, definitions.Callpath)
        self._groups = _RefRegistry(self, Undefined.GROUP, definitions.Group)
        self._metric_members = _RefRegistry(self, Undefined.METRIC_MEMBER, definitions.MetricMember)
        self._parameters = _RefRegistry(self, Undefined.PARAMETER, definitions.Parameter)
        self._rma_wins = _RefRegistry(self, Undefined.RMA_WIN, definitions.RmaWin)
        self._cart_dimensions = _RefRegistry(self, Undefined.CART_DIMENSION, definitions.CartDimension)
        self._cart_topologies = _RefRegistry(self, Undefined.CART_TOPOLOGY, definitions.CartTopology)
        self._source_code_locations = _RefRegistry(self, Undefined.SOURCE_CODE_LOCATION, definitions.SourceCodeLocation)
        self._calling_contexts = _RefRegistry(self, Undefined.CALLING_CONTEXT, definitions.CallingContext)
        self._interrupt_generators = _RefRegistry(self, Undefined.INTERRUPT_GENERATOR, definitions.InterruptGenerator)
        self._io_handles = _RefRegistry(self, Undefined.IO_HANDLE, definitions.IoHandle)

        self._paradigms = _ListRegistry(self, definitions.Paradigm)
        self._paradigm_properties = _ListRegistry(self, definitions.ParadigmProperty)
        self._metric_class_recorders = _ListRegistry(self, definitions.MetricClassRecorder)
        self._system_tree_node_properties = _ListRegistry(self, definitions.SystemTreeNodeProperty)
        self._system_tree_node_domains = _ListRegistry(self, definitions.SystemTreeNodeDomain)
        self._location_group_properties = _ListRegistry(self, definitions.LocationGroupProperty)
        self._location_properties = _ListRegistry(self, definitions.LocationProperty)
        self._cart_coordinates = _ListRegistry(self, definitions.CartCoordinate)
        self._calling_context_properties = _ListRegistry(self, definitions.CallingContextProperty)
        self._io_file_properties = _ListRegistry(self, definitions.IoFileProperty)
        self._io_pre_created_handle_states = _ListRegistry(self, definitions.IoPreCreatedHandleState)
        self._callpath_parameters = _ListRegistry(self, definitions.CallpathParameter)

    def write(self, writer):
        # Warning, the order here is important.
        # That is sometimes not trivial: Groups can refer metrics, but metric instances can
        # refer to groups... So we first write the non-metric groups and then, after metrics,
        # the metric groups
        # Note: The split writing metric groups may violate the strong monotonic order of
        # definition reference

        # Note: We do not write metric classes and instances separately. The order given by the
        # reference will always reflect dependencies from instances on classes
        for thing in chain(self._strings,
                           self._paradigms,
                           self._attributes,
                           self._system_tree_nodes,
                           self._system_tree_node_properties,
                           self._system_tree_node_domains,
                           self._location_groups,
                           self._location_group_properties,
                           self._locations,
                           self._location_properties,
                           self._regions,
                           filter(lambda g: g.group_type != GroupType.METRIC, self._groups),
                           self._metric_members,
                           self._metrics,
                           self._metric_class_recorders,
                           filter(lambda g: g.group_type == GroupType.METRIC, self._groups),
                           self._comms,
                           self._parameters,
                           self._callsites,
                           self._callpaths,
                           self._callpath_parameters,
                           self._rma_wins,
                           self._cart_dimensions,
                           self._cart_topologies,
                           self._cart_coordinates,
                           self._source_code_locations,
                           self._calling_contexts,
                           self._calling_context_properties,
                           self._interrupt_generators,
                           self._paradigm_properties,
                           self._io_paradigms,
                           self._io_files,
                           self._io_file_properties,
                           self._io_handles,
                           self._io_pre_created_handle_states):
            thing.write(writer, self)
        # Make sure all location writers are created, otherwise files will be missing
        for location in self._locations:
            writer._archive.event_writer_from_location(location)

    def _set_global_def_reader_callbacks(self, cbs):
        _otf2.GlobalDefReaderCallbacks_SetClockPropertiesCallback(
            cbs, self._set_clock_properties)
        _otf2.GlobalDefReaderCallbacks_SetMetricClassCallback(
            cbs, self._metrics._callback_gen(definitions.MetricClass))
        _otf2.GlobalDefReaderCallbacks_SetMetricInstanceCallback(
            cbs, self._metrics._callback_gen(definitions.MetricInstance))
        _otf2.GlobalDefReaderCallbacks_SetCommCallback(
            cbs, self._comms._callback_gen(definitions.Comm))
        _otf2.GlobalDefReaderCallbacks_SetIoRegularFileCallback(
            cbs, self._io_files._callback_gen(definitions.IoRegularFile))
        _otf2.GlobalDefReaderCallbacks_SetIoDirectoryCallback(
            cbs, self._io_files._callback_gen(definitions.IoDirectory))
        _otf2.GlobalDefReaderCallbacks_SetInterCommCallback(
            cbs, self._comms._callback_gen(definitions.InterComm))
        _otf2.GlobalDefReaderCallbacks_SetParadigmCallback(
            cbs, self._paradigms._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetParadigmPropertyCallback(
            cbs, self._paradigm_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetIoParadigmCallback(
            cbs, self._io_paradigms._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetStringCallback(
            cbs, self._strings._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetAttributeCallback(
            cbs, self._attributes._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetSystemTreeNodeCallback(
            cbs, self._system_tree_nodes._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetLocationGroupCallback(
            cbs, self._location_groups._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetLocationCallback(
            cbs, self._locations._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetRegionCallback(
            cbs, self._regions._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCallsiteCallback(
            cbs, self._callsites._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCallpathCallback(
            cbs, self._callpaths._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetGroupCallback(
            cbs, self._groups._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetMetricMemberCallback(
            cbs, self._metric_members._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetParameterCallback(
            cbs, self._parameters._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetRmaWinCallback(
            cbs, self._rma_wins._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetMetricClassRecorderCallback(
            cbs, self._metric_class_recorders._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetSystemTreeNodePropertyCallback(
            cbs, self._system_tree_node_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetSystemTreeNodeDomainCallback(
            cbs, self._system_tree_node_domains._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetLocationGroupPropertyCallback(
            cbs, self._location_group_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetLocationPropertyCallback(
            cbs, self._location_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCartDimensionCallback(
            cbs, self._cart_dimensions._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCartTopologyCallback(
            cbs, self._cart_topologies._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCartCoordinateCallback(
            cbs, self._cart_coordinates._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetSourceCodeLocationCallback(
            cbs, self._source_code_locations._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCallingContextCallback(
            cbs, self._calling_contexts._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCallingContextPropertyCallback(
            cbs, self._calling_context_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetInterruptGeneratorCallback(
            cbs, self._interrupt_generators._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetIoFilePropertyCallback(
            cbs, self._io_file_properties._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetIoHandleCallback(
            cbs, self._io_handles._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetIoPreCreatedHandleStateCallback(
            cbs, self._io_pre_created_handle_states._callback_gen())
        _otf2.GlobalDefReaderCallbacks_SetCallpathParameterCallback(
            cbs, self._callpath_parameters._callback_gen())

    def _set_clock_properties(self, _, *args):
        if self.clock_properties is not None:
            raise TraceReaderError("Duplicate ClockProperties entry.")
        self.clock_properties = ClockProperties(None, *args)

    def _string(self, name):
        """
        This function is used internally to intern String definitions.
        They are not exposed publicly, instead, plain str objects are used
        """
        assert type(name) is str
        return self._strings.get(name)

    def _get(self, def_type, ref):
        return self._registry_for_type(def_type)[ref]

    def _registry_for_type(self, def_type):
        if def_type is str:
            return self._strings
        return getattr(self, def_type._registry_name)

    def metric(self, name, *args, **kwargs):
        """
            A convenience method to create a magic metric.
            Details may change in future.

            :param str name: The name for the metric, required argument
        """
        return self.metric_class([self.metric_member(name, *args, **kwargs)])

    @_use_doc_from(definitions.MetricClass)
    def metric_class(self, *args, **kwargs):
        return self._metrics.get(*args, _type=definitions.MetricClass, **kwargs)

    @_use_doc_from(definitions.MetricInstance)
    def metric_instance(self, *args, **kwargs):
        return self._metrics.get(*args, _type=definitions.MetricInstance, **kwargs)

    @_use_doc_from(definitions.Comm)
    def comm(self, *args, **kwargs):
        return self._comms.get(*args, _type=definitions.Comm, **kwargs)

    @_use_doc_from(definitions.IoRegularFile)
    def io_regular_file(self, *args, **kwargs):
        return self._io_files.get(*args, _type=definitions.IoRegularFile, **kwargs)

    @_use_doc_from(definitions.IoDirectory)
    def io_directory(self, *args, **kwargs):
        return self._io_files.get(*args, _type=definitions.IoDirectory, **kwargs)

    @_use_doc_from(definitions.InterComm)
    def inter_comm(self, *args, **kwargs):
        return self._comms.get(*args, _type=definitions.InterComm, **kwargs)

    @_use_doc_from(definitions.IoParadigm)
    def io_paradigm(self, *args, **kwargs):
        return self._io_paradigms.get(*args, **kwargs)

    @_use_doc_from(definitions.Attribute)
    def attribute(self, *args, **kwargs):
        return self._attributes.get(*args, **kwargs)

    @_use_doc_from(definitions.SystemTreeNode)
    def system_tree_node(self, *args, **kwargs):
        return self._system_tree_nodes.get(*args, **kwargs)

    @_use_doc_from(definitions.LocationGroup)
    def location_group(self, *args, **kwargs):
        return self._location_groups.get(*args, **kwargs)

    @_use_doc_from(definitions.Location)
    def location(self, *args, **kwargs):
        return self._locations.get(*args, **kwargs)

    @_use_doc_from(definitions.Region)
    def region(self, *args, **kwargs):
        return self._regions.get(*args, **kwargs)

    @_use_doc_from(definitions.Callsite)
    def callsite(self, *args, **kwargs):
        return self._callsites.get(*args, **kwargs)

    @_use_doc_from(definitions.Callpath)
    def callpath(self, *args, **kwargs):
        return self._callpaths.get(*args, **kwargs)

    @_use_doc_from(definitions.Group)
    def group(self, *args, **kwargs):
        return self._groups.get(*args, **kwargs)

    @_use_doc_from(definitions.MetricMember)
    def metric_member(self, *args, **kwargs):
        return self._metric_members.get(*args, **kwargs)

    @_use_doc_from(definitions.Parameter)
    def parameter(self, *args, **kwargs):
        return self._parameters.get(*args, **kwargs)

    @_use_doc_from(definitions.RmaWin)
    def rma_win(self, *args, **kwargs):
        return self._rma_wins.get(*args, **kwargs)

    @_use_doc_from(definitions.CartDimension)
    def cart_dimension(self, *args, **kwargs):
        return self._cart_dimensions.get(*args, **kwargs)

    @_use_doc_from(definitions.CartTopology)
    def cart_topology(self, *args, **kwargs):
        return self._cart_topologies.get(*args, **kwargs)

    @_use_doc_from(definitions.SourceCodeLocation)
    def source_code_location(self, *args, **kwargs):
        return self._source_code_locations.get(*args, **kwargs)

    @_use_doc_from(definitions.CallingContext)
    def calling_context(self, *args, **kwargs):
        return self._calling_contexts.get(*args, **kwargs)

    @_use_doc_from(definitions.InterruptGenerator)
    def interrupt_generator(self, *args, **kwargs):
        return self._interrupt_generators.get(*args, **kwargs)

    @_use_doc_from(definitions.IoHandle)
    def io_handle(self, *args, **kwargs):
        return self._io_handles.get(*args, **kwargs)

    @_use_doc_from(definitions.Paradigm)
    def paradigm(self, *args, **kwargs):
        return self._paradigms.create(*args, **kwargs)

    @_use_doc_from(definitions.ParadigmProperty)
    def paradigm_property(self, *args, **kwargs):
        return self._paradigm_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.MetricClassRecorder)
    def metric_class_recorder(self, *args, **kwargs):
        return self._metric_class_recorders.create(*args, **kwargs)

    @_use_doc_from(definitions.SystemTreeNodeProperty)
    def system_tree_node_property(self, *args, **kwargs):
        return self._system_tree_node_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.SystemTreeNodeDomain)
    def system_tree_node_domain(self, *args, **kwargs):
        return self._system_tree_node_domains.create(*args, **kwargs)

    @_use_doc_from(definitions.LocationGroupProperty)
    def location_group_property(self, *args, **kwargs):
        return self._location_group_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.LocationProperty)
    def location_property(self, *args, **kwargs):
        return self._location_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.CartCoordinate)
    def cart_coordinate(self, *args, **kwargs):
        return self._cart_coordinates.create(*args, **kwargs)

    @_use_doc_from(definitions.CallingContextProperty)
    def calling_context_property(self, *args, **kwargs):
        return self._calling_context_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.IoFileProperty)
    def io_file_property(self, *args, **kwargs):
        return self._io_file_properties.create(*args, **kwargs)

    @_use_doc_from(definitions.IoPreCreatedHandleState)
    def io_pre_created_handle_state(self, *args, **kwargs):
        return self._io_pre_created_handle_states.create(*args, **kwargs)

    @_use_doc_from(definitions.CallpathParameter)
    def callpath_parameter(self, *args, **kwargs):
        return self._callpath_parameters.create(*args, **kwargs)

    @property
    def strings(self):
        """
            A :py:class:`_Registry` instance representing all String definitons.
        """
        return self._strings

    @property
    def metric_classes(self):
        return filter(lambda m: isinstance(m, definitions.MetricClass), self._metrics)

    @property
    def metric_instances(self):
        return filter(lambda m: isinstance(m, definitions.MetricInstance), self._metrics)

    @property
    def comms(self):
        return filter(lambda m: isinstance(m, definitions.Comm), self._comms)

    @property
    def io_regular_files(self):
        return filter(lambda m: isinstance(m, definitions.IoRegularFile), self._io_files)

    @property
    def io_directories(self):
        return filter(lambda m: isinstance(m, definitions.IoDirectory), self._io_files)

    @property
    def inter_comms(self):
        return filter(lambda m: isinstance(m, definitions.InterComm), self._comms)

    @property
    def io_paradigms(self):
        """
            A :py:class:`_Registry` instance representing all IoParadigm definitons.
        """
        return self._io_paradigms

    @property
    def attributes(self):
        """
            A :py:class:`_Registry` instance representing all Attribute definitons.
        """
        return self._attributes

    @property
    def system_tree_nodes(self):
        """
            A :py:class:`_Registry` instance representing all SystemTreeNode definitons.
        """
        return self._system_tree_nodes

    @property
    def location_groups(self):
        """
            A :py:class:`_Registry` instance representing all LocationGroup definitons.
        """
        return self._location_groups

    @property
    def locations(self):
        """
            A :py:class:`_Registry` instance representing all Location definitons.
        """
        return self._locations

    @property
    def regions(self):
        """
            A :py:class:`_Registry` instance representing all Region definitons.
        """
        return self._regions

    @property
    def callsites(self):
        """
            A :py:class:`_Registry` instance representing all Callsite definitons.
        """
        return self._callsites

    @property
    def callpaths(self):
        """
            A :py:class:`_Registry` instance representing all Callpath definitons.
        """
        return self._callpaths

    @property
    def groups(self):
        """
            A :py:class:`_Registry` instance representing all Group definitons.
        """
        return self._groups

    @property
    def metric_members(self):
        """
            A :py:class:`_Registry` instance representing all MetricMember definitons.
        """
        return self._metric_members

    @property
    def metrics(self):
        """
            A :py:class:`_Registry` instance representing all Metric definitons.
        """
        return self._metrics

    @property
    def comms(self):
        """
            A :py:class:`_Registry` instance representing all Comm definitons.
        """
        return self._comms

    @property
    def parameters(self):
        """
            A :py:class:`_Registry` instance representing all Parameter definitons.
        """
        return self._parameters

    @property
    def rma_wins(self):
        """
            A :py:class:`_Registry` instance representing all RmaWin definitons.
        """
        return self._rma_wins

    @property
    def cart_dimensions(self):
        """
            A :py:class:`_Registry` instance representing all CartDimension definitons.
        """
        return self._cart_dimensions

    @property
    def cart_topologies(self):
        """
            A :py:class:`_Registry` instance representing all CartTopology definitons.
        """
        return self._cart_topologies

    @property
    def source_code_locations(self):
        """
            A :py:class:`_Registry` instance representing all SourceCodeLocation definitons.
        """
        return self._source_code_locations

    @property
    def calling_contexts(self):
        """
            A :py:class:`_Registry` instance representing all CallingContext definitons.
        """
        return self._calling_contexts

    @property
    def interrupt_generators(self):
        """
            A :py:class:`_Registry` instance representing all InterruptGenerator definitons.
        """
        return self._interrupt_generators

    @property
    def io_files(self):
        """
            A :py:class:`_Registry` instance representing all IoFile definitons.
        """
        return self._io_files

    @property
    def io_handles(self):
        """
            A :py:class:`_Registry` instance representing all IoHandle definitons.
        """
        return self._io_handles

    @property
    def paradigms(self):
        """
            A :py:class:`_Registry` instance representing all Paradigm definitons.
        """
        return self._paradigms

    @property
    def paradigm_properties(self):
        """
            A :py:class:`_Registry` instance representing all ParadigmProperty definitons.
        """
        return self._paradigm_properties

    @property
    def metric_class_recorders(self):
        """
            A :py:class:`_Registry` instance representing all MetricClassRecorder definitons.
        """
        return self._metric_class_recorders

    @property
    def system_tree_node_properties(self):
        """
            A :py:class:`_Registry` instance representing all SystemTreeNodeProperty definitons.
        """
        return self._system_tree_node_properties

    @property
    def system_tree_node_domains(self):
        """
            A :py:class:`_Registry` instance representing all SystemTreeNodeDomain definitons.
        """
        return self._system_tree_node_domains

    @property
    def location_group_properties(self):
        """
            A :py:class:`_Registry` instance representing all LocationGroupProperty definitons.
        """
        return self._location_group_properties

    @property
    def location_properties(self):
        """
            A :py:class:`_Registry` instance representing all LocationProperty definitons.
        """
        return self._location_properties

    @property
    def cart_coordinates(self):
        """
            A :py:class:`_Registry` instance representing all CartCoordinate definitons.
        """
        return self._cart_coordinates

    @property
    def calling_context_properties(self):
        """
            A :py:class:`_Registry` instance representing all CallingContextProperty definitons.
        """
        return self._calling_context_properties

    @property
    def io_file_properties(self):
        """
            A :py:class:`_Registry` instance representing all IoFileProperty definitons.
        """
        return self._io_file_properties

    @property
    def io_pre_created_handle_states(self):
        """
            A :py:class:`_Registry` instance representing all IoPreCreatedHandleState definitons.
        """
        return self._io_pre_created_handle_states

    @property
    def callpath_parameters(self):
        """
            A :py:class:`_Registry` instance representing all CallpathParameter definitons.
        """
        return self._callpath_parameters
