<filename>test_cases/general/forward_declaration/py/test_generate/fromjsonable.py<gh_stars>10-100
# File automatically generated by mapry. DO NOT EDIT OR APPEND!


"""parses JSONable objects."""


import collections
import typing

import some.graph
import some.graph.parse


def _some_class_from(
        value: typing.Any,
        other_classes_registry: typing.Mapping[
            str,
            some.graph.OtherClass],
        some_classes_registry: typing.Mapping[
            str,
            some.graph.SomeClass],
        ref: str,
        target: some.graph.SomeClass,
        errors: some.graph.parse.Errors
) -> None:
    """
    parses SomeClass from a JSONable value.

    If ``errors``, the attributes of ``target`` have undefined values.

    :param value: JSONable value
    :param other_classes_registry: registry of the OtherClass instances
    :param some_classes_registry: registry of the SomeClass instances
    :param ref:
        reference to the value (e.g., a reference path)
    :param target: parsed ``value`` as SomeClass
    :param errors: errors encountered during parsing
    :return:

    """
    if not isinstance(value, dict):
        errors.add(
            ref,
            "Expected a dictionary, but got: {}".format(
                type(value)))
        return

    ##
    # Parse reference_other
    ##

    value_0 = value.get(
        'reference_other',
        None)

    if value_0 is None:
        errors.add(
            ref,
            'Property is missing: reference_other')
    else:
        if not isinstance(value_0, str):
            errors.add(
                '/'.join((
                    ref, 'reference_other')),
                "Expected a str, but got: {}".format(
                    type(value_0)))
        else:
            target_1 = other_classes_registry.get(
                value_0,
                None)
            if target_1 is None:
                errors.add(
                    '/'.join((
                        ref, 'reference_other')),
                    'Reference to an instance of class Other_class not found: {}'.format(
                        value_0))
            else:
                target.reference_other = target_1
    if errors.full():
        return

    ##
    # Parse array_of_others
    ##

    value_2 = value.get(
        'array_of_others',
        None)

    if value_2 is None:
        errors.add(
            ref,
            'Property is missing: array_of_others')
    else:
        if not isinstance(value_2, list):
            errors.add(
                '/'.join((
                    ref, 'array_of_others')),
                "Expected a list, but got: {}".format(
                    type(value_2)))
        else:
            target_3 = (
                []
            )  # type: typing.List[some.graph.OtherClass]
            for i_3, item_3 in enumerate(
                    value_2):
                target_item_3 = (
                    None
                )  # type: typing.Optional[some.graph.OtherClass]
                if not isinstance(item_3, str):
                    errors.add(
                        '/'.join((
                            ref, 'array_of_others', str(i_3))),
                        "Expected a str, but got: {}".format(
                            type(item_3)))
                else:
                    target_4 = other_classes_registry.get(
                        item_3,
                        None)
                    if target_4 is None:
                        errors.add(
                            '/'.join((
                                ref, 'array_of_others', str(i_3))),
                            'Reference to an instance of class Other_class not found: {}'.format(
                                item_3))
                    else:
                        target_item_3 = target_4

                if target_item_3 is not None:
                    target_3.append(
                        target_item_3)

                if errors.full():
                    break

            target.array_of_others = target_3
    if errors.full():
        return

    ##
    # Parse map_of_others
    ##

    value_5 = value.get(
        'map_of_others',
        None)

    if value_5 is None:
        errors.add(
            ref,
            'Property is missing: map_of_others')
    else:
        if not isinstance(value_5, dict):
            errors.add(
                '/'.join((
                    ref, 'map_of_others')),
                "Expected a dict, but got: {}".format(
                    type(value_5)))
        else:
            if isinstance(value_5, collections.OrderedDict):
                target_6 = (
                    collections.OrderedDict()
                )  # type: typing.MutableMapping[str, some.graph.OtherClass]
            else:
                target_6 = (
                    dict()
                )

            for key_6, value_6 in value_5.items():
                if not isinstance(key_6, str):
                    errors.add(
                        '/'.join((
                            ref, 'map_of_others')),
                        "Expected the key to be a str, but got: {}".format(
                            type(key_6)))

                    if errors.full():
                        break
                    else:
                        continue

                target_item_6 = (
                    None
                )  # type: typing.Optional[some.graph.OtherClass]
                if not isinstance(value_6, str):
                    errors.add(
                        '/'.join((
                            ref, 'map_of_others', repr(key_6))),
                        "Expected a str, but got: {}".format(
                            type(value_6)))
                else:
                    target_7 = other_classes_registry.get(
                        value_6,
                        None)
                    if target_7 is None:
                        errors.add(
                            '/'.join((
                                ref, 'map_of_others', repr(key_6))),
                            'Reference to an instance of class Other_class not found: {}'.format(
                                value_6))
                    else:
                        target_item_6 = target_7

                if target_item_6 is not None:
                    target_6[key_6] = target_item_6

                if errors.full():
                    break

            if target_6 is not None:
                target.map_of_others = target_6
    if errors.full():
        return


def some_class_from(
        value: typing.Any,
        id: str,
        other_classes_registry: typing.Mapping[
            str,
            some.graph.OtherClass],
        some_classes_registry: typing.Mapping[
            str,
            some.graph.SomeClass],
        ref: str,
        errors: some.graph.parse.Errors
) -> typing.Optional[some.graph.SomeClass]:
    """
    parses SomeClass from a JSONable value.

    :param value: JSONable value
    :param id: identifier of the instance
    :param other_classes_registry:
        registry of the OtherClass instances
    :param some_classes_registry:
        registry of the SomeClass instances
    :param ref:
        reference to the value (e.g., a reference path)
    :param errors: errors encountered during parsing
    :return: parsed instance, or None if ``errors``

    """
    target = some.graph.parse.placeholder_some_class(id=id)

    _some_class_from(
        value=value,
        other_classes_registry=other_classes_registry,
        some_classes_registry=some_classes_registry,
        ref=ref,
        target=target,
        errors=errors)

    if not errors.empty():
       return None

    return target


def _other_class_from(
        value: typing.Any,
        other_classes_registry: typing.Mapping[
            str,
            some.graph.OtherClass],
        some_classes_registry: typing.Mapping[
            str,
            some.graph.SomeClass],
        ref: str,
        target: some.graph.OtherClass,
        errors: some.graph.parse.Errors
) -> None:
    """
    parses OtherClass from a JSONable value.

    If ``errors``, the attributes of ``target`` have undefined values.

    :param value: JSONable value
    :param other_classes_registry: registry of the OtherClass instances
    :param some_classes_registry: registry of the SomeClass instances
    :param ref:
        reference to the value (e.g., a reference path)
    :param target: parsed ``value`` as OtherClass
    :param errors: errors encountered during parsing
    :return:

    """
    if not isinstance(value, dict):
        errors.add(
            ref,
            "Expected a dictionary, but got: {}".format(
                type(value)))
        return

    ##
    # Parse reference_some
    ##

    value_0 = value.get(
        'reference_some',
        None)

    if value_0 is None:
        errors.add(
            ref,
            'Property is missing: reference_some')
    else:
        if not isinstance(value_0, str):
            errors.add(
                '/'.join((
                    ref, 'reference_some')),
                "Expected a str, but got: {}".format(
                    type(value_0)))
        else:
            target_1 = some_classes_registry.get(
                value_0,
                None)
            if target_1 is None:
                errors.add(
                    '/'.join((
                        ref, 'reference_some')),
                    'Reference to an instance of class Some_class not found: {}'.format(
                        value_0))
            else:
                target.reference_some = target_1
    if errors.full():
        return

    ##
    # Parse array_of_somes
    ##

    value_2 = value.get(
        'array_of_somes',
        None)

    if value_2 is None:
        errors.add(
            ref,
            'Property is missing: array_of_somes')
    else:
        if not isinstance(value_2, list):
            errors.add(
                '/'.join((
                    ref, 'array_of_somes')),
                "Expected a list, but got: {}".format(
                    type(value_2)))
        else:
            target_3 = (
                []
            )  # type: typing.List[some.graph.SomeClass]
            for i_3, item_3 in enumerate(
                    value_2):
                target_item_3 = (
                    None
                )  # type: typing.Optional[some.graph.SomeClass]
                if not isinstance(item_3, str):
                    errors.add(
                        '/'.join((
                            ref, 'array_of_somes', str(i_3))),
                        "Expected a str, but got: {}".format(
                            type(item_3)))
                else:
                    target_4 = some_classes_registry.get(
                        item_3,
                        None)
                    if target_4 is None:
                        errors.add(
                            '/'.join((
                                ref, 'array_of_somes', str(i_3))),
                            'Reference to an instance of class Some_class not found: {}'.format(
                                item_3))
                    else:
                        target_item_3 = target_4

                if target_item_3 is not None:
                    target_3.append(
                        target_item_3)

                if errors.full():
                    break

            target.array_of_somes = target_3
    if errors.full():
        return

    ##
    # Parse map_of_somes
    ##

    value_5 = value.get(
        'map_of_somes',
        None)

    if value_5 is None:
        errors.add(
            ref,
            'Property is missing: map_of_somes')
    else:
        if not isinstance(value_5, dict):
            errors.add(
                '/'.join((
                    ref, 'map_of_somes')),
                "Expected a dict, but got: {}".format(
                    type(value_5)))
        else:
            if isinstance(value_5, collections.OrderedDict):
                target_6 = (
                    collections.OrderedDict()
                )  # type: typing.MutableMapping[str, some.graph.SomeClass]
            else:
                target_6 = (
                    dict()
                )

            for key_6, value_6 in value_5.items():
                if not isinstance(key_6, str):
                    errors.add(
                        '/'.join((
                            ref, 'map_of_somes')),
                        "Expected the key to be a str, but got: {}".format(
                            type(key_6)))

                    if errors.full():
                        break
                    else:
                        continue

                target_item_6 = (
                    None
                )  # type: typing.Optional[some.graph.SomeClass]
                if not isinstance(value_6, str):
                    errors.add(
                        '/'.join((
                            ref, 'map_of_somes', repr(key_6))),
                        "Expected a str, but got: {}".format(
                            type(value_6)))
                else:
                    target_7 = some_classes_registry.get(
                        value_6,
                        None)
                    if target_7 is None:
                        errors.add(
                            '/'.join((
                                ref, 'map_of_somes', repr(key_6))),
                            'Reference to an instance of class Some_class not found: {}'.format(
                                value_6))
                    else:
                        target_item_6 = target_7

                if target_item_6 is not None:
                    target_6[key_6] = target_item_6

                if errors.full():
                    break

            if target_6 is not None:
                target.map_of_somes = target_6
    if errors.full():
        return


def other_class_from(
        value: typing.Any,
        id: str,
        other_classes_registry: typing.Mapping[
            str,
            some.graph.OtherClass],
        some_classes_registry: typing.Mapping[
            str,
            some.graph.SomeClass],
        ref: str,
        errors: some.graph.parse.Errors
) -> typing.Optional[some.graph.OtherClass]:
    """
    parses OtherClass from a JSONable value.

    :param value: JSONable value
    :param id: identifier of the instance
    :param other_classes_registry:
        registry of the OtherClass instances
    :param some_classes_registry:
        registry of the SomeClass instances
    :param ref:
        reference to the value (e.g., a reference path)
    :param errors: errors encountered during parsing
    :return: parsed instance, or None if ``errors``

    """
    target = some.graph.parse.placeholder_other_class(id=id)

    _other_class_from(
        value=value,
        other_classes_registry=other_classes_registry,
        some_classes_registry=some_classes_registry,
        ref=ref,
        target=target,
        errors=errors)

    if not errors.empty():
       return None

    return target


def some_graph_from(
        value: typing.Any,
        ref: str,
        errors: some.graph.parse.Errors
) -> typing.Optional[some.graph.SomeGraph]:
    """
    parses SomeGraph from a JSONable value.

    :param value: JSONable value
    :param ref: reference to the value (e.g., a reference path)
    :param errors: errors encountered during parsing
    :return: parsed SomeGraph, or None if ``errors``
    """
    if errors.full():
        return None

    if not isinstance(value, dict):
        errors.add(
            ref,
            "Expected a dictionary, but got: {}".format(type(value)))
        return None

    graph = some.graph.parse.placeholder_some_graph()

    ##
    # Pre-allocate some_classes
    ##

    registry_value = value.get('some_classes', None)

    if registry_value is not None:
        if not isinstance(registry_value, dict):
            errors.add(
                '/'.join((
                    ref, 'some_classes')),
                "Expected a dictionary, but got: {}".format(
                    type(registry_value)))
        else:
            if isinstance(registry_value, collections.OrderedDict):
                graph.some_classes = collections.OrderedDict()
            else:
                graph.some_classes = dict()

            some_classes_registry = graph.some_classes
            for id in registry_value:
                some_classes_registry[id] = some.graph.parse.placeholder_some_class(id=id)

    if errors.full():
        return None

    ##
    # Pre-allocate other_classes
    ##

    registry_value = value.get('other_classes', None)

    if registry_value is not None:
        if not isinstance(registry_value, dict):
            errors.add(
                '/'.join((
                    ref, 'other_classes')),
                "Expected a dictionary, but got: {}".format(
                    type(registry_value)))
        else:
            if isinstance(registry_value, collections.OrderedDict):
                graph.other_classes = collections.OrderedDict()
            else:
                graph.other_classes = dict()

            other_classes_registry = graph.other_classes
            for id in registry_value:
                other_classes_registry[id] = some.graph.parse.placeholder_other_class(id=id)

    if errors.full():
        return None

    # Errors from pre-allocation are considered critical.
    if not errors.empty():
        return None

    ##
    # Parse some_classes
    ##

    if 'some_classes' in value:
        registry_value = value['some_classes']
        for id, instance_value in registry_value.items():
            target_some_class = graph.some_classes[id]
            target_some_class.id = id

            _some_class_from(
                instance_value,
                graph.other_classes,
                graph.some_classes,
                '/'.join((
                    ref, 'some_classes', repr(id))),
                target_some_class,
                errors)

            if errors.full():
                return None

    ##
    # Parse other_classes
    ##

    if 'other_classes' in value:
        registry_value = value['other_classes']
        for id, instance_value in registry_value.items():
            target_other_class = graph.other_classes[id]
            target_other_class.id = id

            _other_class_from(
                instance_value,
                graph.other_classes,
                graph.some_classes,
                '/'.join((
                    ref, 'other_classes', repr(id))),
                target_other_class,
                errors)

            if errors.full():
                return None

    if not errors.empty():
        return None

    return graph
