"""Generated by atdpy from type definitions in ast_generic_v1.atd.

This implements classes for the types defined in 'ast_generic_v1.atd', providing
methods and functions to convert data from/to JSON.
"""

# Disable flake8 entirely on this file:
# flake8: noqa

# Import annotations to allow forward references
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, NoReturn, Optional, Tuple, Union

import json

############################################################################
# Private functions
############################################################################


def _atd_missing_json_field(type_name: str, json_field_name: str) -> NoReturn:
    raise ValueError(f"missing field '{json_field_name}'"
                     f" in JSON object of type '{type_name}'")


def _atd_bad_json(expected_type: str, json_value: Any) -> NoReturn:
    value_str = str(json_value)
    if len(value_str) > 200:
        value_str = value_str[:200] + '…'

    raise ValueError(f"incompatible JSON value where"
                     f" type '{expected_type}' was expected: '{value_str}'")


def _atd_bad_python(expected_type: str, json_value: Any) -> NoReturn:
    value_str = str(json_value)
    if len(value_str) > 200:
        value_str = value_str[:200] + '…'

    raise ValueError(f"incompatible Python value where"
                     f" type '{expected_type}' was expected: '{value_str}'")


def _atd_read_unit(x: Any) -> None:
    if x is None:
        return x
    else:
        _atd_bad_json('unit', x)


def _atd_read_bool(x: Any) -> bool:
    if isinstance(x, bool):
        return x
    else:
        _atd_bad_json('bool', x)


def _atd_read_int(x: Any) -> int:
    if isinstance(x, int):
        return x
    else:
        _atd_bad_json('int', x)


def _atd_read_float(x: Any) -> float:
    if isinstance(x, (int, float)):
        return x
    else:
        _atd_bad_json('float', x)


def _atd_read_string(x: Any) -> str:
    if isinstance(x, str):
        return x
    else:
        _atd_bad_json('str', x)


def _atd_read_list(
            read_elt: Callable[[Any], Any]
        ) -> Callable[[List[Any]], List[Any]]:
    def read_list(elts: List[Any]) -> List[Any]:
        if isinstance(elts, list):
            return [read_elt(elt) for elt in elts]
        else:
            _atd_bad_json('array', elts)
    return read_list


def _atd_read_assoc_array_into_dict(
            read_key: Callable[[Any], Any],
            read_value: Callable[[Any], Any],
        ) -> Callable[[List[Any]], Dict[Any, Any]]:
    def read_assoc(elts: List[List[Any]]) -> Dict[str, Any]:
        if isinstance(elts, list):
            return {read_key(elt[0]): read_value(elt[1]) for elt in elts}
        else:
            _atd_bad_json('array', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return read_assoc


def _atd_read_assoc_object_into_dict(
            read_value: Callable[[Any], Any]
        ) -> Callable[[Dict[str, Any]], Dict[str, Any]]:
    def read_assoc(elts: Dict[str, Any]) -> Dict[str, Any]:
        if isinstance(elts, dict):
            return {_atd_read_string(k): read_value(v)
                    for k, v in elts.items()}
        else:
            _atd_bad_json('object', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return read_assoc


def _atd_read_assoc_object_into_list(
            read_value: Callable[[Any], Any]
        ) -> Callable[[Dict[str, Any]], List[Tuple[str, Any]]]:
    def read_assoc(elts: Dict[str, Any]) -> List[Tuple[str, Any]]:
        if isinstance(elts, dict):
            return [(_atd_read_string(k), read_value(v))
                    for k, v in elts.items()]
        else:
            _atd_bad_json('object', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return read_assoc


def _atd_read_nullable(read_elt: Callable[[Any], Any]) \
        -> Callable[[Optional[Any]], Optional[Any]]:
    def read_nullable(x: Any) -> Any:
        if x is None:
            return None
        else:
            return read_elt(x)
    return read_nullable


def _atd_write_unit(x: Any) -> None:
    if x is None:
        return x
    else:
        _atd_bad_python('unit', x)


def _atd_write_bool(x: Any) -> bool:
    if isinstance(x, bool):
        return x
    else:
        _atd_bad_python('bool', x)


def _atd_write_int(x: Any) -> int:
    if isinstance(x, int):
        return x
    else:
        _atd_bad_python('int', x)


def _atd_write_float(x: Any) -> float:
    if isinstance(x, (int, float)):
        return x
    else:
        _atd_bad_python('float', x)


def _atd_write_string(x: Any) -> str:
    if isinstance(x, str):
        return x
    else:
        _atd_bad_python('str', x)


def _atd_write_list(
            write_elt: Callable[[Any], Any]
        ) -> Callable[[List[Any]], List[Any]]:
    def write_list(elts: List[Any]) -> List[Any]:
        if isinstance(elts, list):
            return [write_elt(elt) for elt in elts]
        else:
            _atd_bad_python('list', elts)
    return write_list


def _atd_write_assoc_dict_to_array(
            write_key: Callable[[Any], Any],
            write_value: Callable[[Any], Any]
        ) -> Callable[[Dict[Any, Any]], List[Tuple[Any, Any]]]:
    def write_assoc(elts: Dict[str, Any]) -> List[Tuple[str, Any]]:
        if isinstance(elts, dict):
            return [(write_key(k), write_value(v)) for k, v in elts.items()]
        else:
            _atd_bad_python('Dict[str, <value type>]]', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return write_assoc


def _atd_write_assoc_dict_to_object(
            write_value: Callable[[Any], Any]
        ) -> Callable[[Dict[str, Any]], Dict[str, Any]]:
    def write_assoc(elts: Dict[str, Any]) -> Dict[str, Any]:
        if isinstance(elts, dict):
            return {_atd_write_string(k): write_value(v)
                    for k, v in elts.items()}
        else:
            _atd_bad_python('Dict[str, <value type>]', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return write_assoc


def _atd_write_assoc_list_to_object(
            write_value: Callable[[Any], Any],
        ) -> Callable[[List[Any]], Dict[str, Any]]:
    def write_assoc(elts: List[List[Any]]) -> Dict[str, Any]:
        if isinstance(elts, list):
            return {_atd_write_string(elt[0]): write_value(elt[1])
                    for elt in elts}
        else:
            _atd_bad_python('List[Tuple[<key type>, <value type>]]', elts)
            raise AssertionError('impossible')  # keep mypy happy
    return write_assoc


def _atd_write_nullable(write_elt: Callable[[Any], Any]) \
        -> Callable[[Optional[Any]], Optional[Any]]:
    def write_nullable(x: Any) -> Any:
        if x is None:
            return None
        else:
            return write_elt(x)
    return write_nullable


############################################################################
# Public classes
############################################################################


@dataclass
class Class:
    """Original type: class_kind = [ ... | Class | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Class'

    @staticmethod
    def to_json() -> Any:
        return 'Class'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Interface:
    """Original type: class_kind = [ ... | Interface | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Interface'

    @staticmethod
    def to_json() -> Any:
        return 'Interface'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Trait:
    """Original type: class_kind = [ ... | Trait | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Trait'

    @staticmethod
    def to_json() -> Any:
        return 'Trait'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Object:
    """Original type: class_kind = [ ... | Object | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Object'

    @staticmethod
    def to_json() -> Any:
        return 'Object'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ClassKind:
    """Original type: class_kind = [ ... ]"""

    value: Union[Class, Interface, Trait, Object]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ClassKind':
        if isinstance(x, str):
            if x == 'Class':
                return cls(Class())
            if x == 'Interface':
                return cls(Interface())
            if x == 'Trait':
                return cls(Trait())
            if x == 'Object':
                return cls(Object())
            _atd_bad_json('ClassKind', x)
        _atd_bad_json('ClassKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ClassKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class InterpolatedConcat:
    """Original type: concat_string_kind = [ ... | InterpolatedConcat | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'InterpolatedConcat'

    @staticmethod
    def to_json() -> Any:
        return 'InterpolatedConcat'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class SequenceConcat:
    """Original type: concat_string_kind = [ ... | SequenceConcat | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'SequenceConcat'

    @staticmethod
    def to_json() -> Any:
        return 'SequenceConcat'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FString:
    """Original type: concat_string_kind = [ ... | FString of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FString'

    def to_json(self) -> Any:
        return ['FString', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TaggedTemplateLiteral:
    """Original type: concat_string_kind = [ ... | TaggedTemplateLiteral | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TaggedTemplateLiteral'

    @staticmethod
    def to_json() -> Any:
        return 'TaggedTemplateLiteral'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ConcatStringKind:
    """Original type: concat_string_kind = [ ... ]"""

    value: Union[InterpolatedConcat, SequenceConcat, FString, TaggedTemplateLiteral]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ConcatStringKind':
        if isinstance(x, str):
            if x == 'InterpolatedConcat':
                return cls(InterpolatedConcat())
            if x == 'SequenceConcat':
                return cls(SequenceConcat())
            if x == 'TaggedTemplateLiteral':
                return cls(TaggedTemplateLiteral())
            _atd_bad_json('ConcatStringKind', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'FString':
                return cls(FString(_atd_read_string(x[1])))
            _atd_bad_json('ConcatStringKind', x)
        _atd_bad_json('ConcatStringKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ConcatStringKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cbool:
    """Original type: const_type = [ ... | Cbool | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cbool'

    @staticmethod
    def to_json() -> Any:
        return 'Cbool'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cint:
    """Original type: const_type = [ ... | Cint | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cint'

    @staticmethod
    def to_json() -> Any:
        return 'Cint'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cstr:
    """Original type: const_type = [ ... | Cstr | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cstr'

    @staticmethod
    def to_json() -> Any:
        return 'Cstr'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cany:
    """Original type: const_type = [ ... | Cany | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cany'

    @staticmethod
    def to_json() -> Any:
        return 'Cany'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ConstType:
    """Original type: const_type = [ ... ]"""

    value: Union[Cbool, Cint, Cstr, Cany]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ConstType':
        if isinstance(x, str):
            if x == 'Cbool':
                return cls(Cbool())
            if x == 'Cint':
                return cls(Cint())
            if x == 'Cstr':
                return cls(Cstr())
            if x == 'Cany':
                return cls(Cany())
            _atd_bad_json('ConstType', x)
        _atd_bad_json('ConstType', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ConstType':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Array:
    """Original type: container_operator = [ ... | Array | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Array'

    @staticmethod
    def to_json() -> Any:
        return 'Array'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class List_:
    """Original type: container_operator = [ ... | List | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'List_'

    @staticmethod
    def to_json() -> Any:
        return 'List'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Set:
    """Original type: container_operator = [ ... | Set | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Set'

    @staticmethod
    def to_json() -> Any:
        return 'Set'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Dict_:
    """Original type: container_operator = [ ... | Dict | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Dict_'

    @staticmethod
    def to_json() -> Any:
        return 'Dict'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Tuple_:
    """Original type: container_operator = [ ... | Tuple | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Tuple_'

    @staticmethod
    def to_json() -> Any:
        return 'Tuple'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ContainerOperator:
    """Original type: container_operator = [ ... ]"""

    value: Union[Array, List_, Set, Dict_, Tuple_]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ContainerOperator':
        if isinstance(x, str):
            if x == 'Array':
                return cls(Array())
            if x == 'List':
                return cls(List_())
            if x == 'Set':
                return cls(Set())
            if x == 'Dict':
                return cls(Dict_())
            if x == 'Tuple':
                return cls(Tuple_())
            _atd_bad_json('ContainerOperator', x)
        _atd_bad_json('ContainerOperator', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ContainerOperator':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Function:
    """Original type: function_kind = [ ... | Function | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Function'

    @staticmethod
    def to_json() -> Any:
        return 'Function'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Method:
    """Original type: function_kind = [ ... | Method | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Method'

    @staticmethod
    def to_json() -> Any:
        return 'Method'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LambdaKind:
    """Original type: function_kind = [ ... | LambdaKind | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LambdaKind'

    @staticmethod
    def to_json() -> Any:
        return 'LambdaKind'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Arrow:
    """Original type: function_kind = [ ... | Arrow | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Arrow'

    @staticmethod
    def to_json() -> Any:
        return 'Arrow'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BlockCases:
    """Original type: function_kind = [ ... | BlockCases | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BlockCases'

    @staticmethod
    def to_json() -> Any:
        return 'BlockCases'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FunctionKind:
    """Original type: function_kind = [ ... ]"""

    value: Union[Function, Method, LambdaKind, Arrow, BlockCases]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'FunctionKind':
        if isinstance(x, str):
            if x == 'Function':
                return cls(Function())
            if x == 'Method':
                return cls(Method())
            if x == 'LambdaKind':
                return cls(LambdaKind())
            if x == 'Arrow':
                return cls(Arrow())
            if x == 'BlockCases':
                return cls(BlockCases())
            _atd_bad_json('FunctionKind', x)
        _atd_bad_json('FunctionKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'FunctionKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Incr:
    """Original type: incr_decr = [ ... | Incr | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Incr'

    @staticmethod
    def to_json() -> Any:
        return 'Incr'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Decr:
    """Original type: incr_decr = [ ... | Decr | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Decr'

    @staticmethod
    def to_json() -> Any:
        return 'Decr'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IncrDecr:
    """Original type: incr_decr = [ ... ]"""

    value: Union[Incr, Decr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'IncrDecr':
        if isinstance(x, str):
            if x == 'Incr':
                return cls(Incr())
            if x == 'Decr':
                return cls(Decr())
            _atd_bad_json('IncrDecr', x)
        _atd_bad_json('IncrDecr', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'IncrDecr':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Static:
    """Original type: keyword_attribute = [ ... | Static | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Static'

    @staticmethod
    def to_json() -> Any:
        return 'Static'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Volatile:
    """Original type: keyword_attribute = [ ... | Volatile | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Volatile'

    @staticmethod
    def to_json() -> Any:
        return 'Volatile'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Extern:
    """Original type: keyword_attribute = [ ... | Extern | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Extern'

    @staticmethod
    def to_json() -> Any:
        return 'Extern'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Public:
    """Original type: keyword_attribute = [ ... | Public | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Public'

    @staticmethod
    def to_json() -> Any:
        return 'Public'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Private:
    """Original type: keyword_attribute = [ ... | Private | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Private'

    @staticmethod
    def to_json() -> Any:
        return 'Private'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Protected:
    """Original type: keyword_attribute = [ ... | Protected | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Protected'

    @staticmethod
    def to_json() -> Any:
        return 'Protected'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Abstract:
    """Original type: keyword_attribute = [ ... | Abstract | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Abstract'

    @staticmethod
    def to_json() -> Any:
        return 'Abstract'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Final:
    """Original type: keyword_attribute = [ ... | Final | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Final'

    @staticmethod
    def to_json() -> Any:
        return 'Final'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Override:
    """Original type: keyword_attribute = [ ... | Override | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Override'

    @staticmethod
    def to_json() -> Any:
        return 'Override'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class RecordClass:
    """Original type: keyword_attribute = [ ... | RecordClass | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'RecordClass'

    @staticmethod
    def to_json() -> Any:
        return 'RecordClass'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AnnotationClass:
    """Original type: keyword_attribute = [ ... | AnnotationClass | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AnnotationClass'

    @staticmethod
    def to_json() -> Any:
        return 'AnnotationClass'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EnumClass:
    """Original type: keyword_attribute = [ ... | EnumClass | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EnumClass'

    @staticmethod
    def to_json() -> Any:
        return 'EnumClass'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class SealedClass:
    """Original type: keyword_attribute = [ ... | SealedClass | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'SealedClass'

    @staticmethod
    def to_json() -> Any:
        return 'SealedClass'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Var:
    """Original type: keyword_attribute = [ ... | Var | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Var'

    @staticmethod
    def to_json() -> Any:
        return 'Var'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Let:
    """Original type: keyword_attribute = [ ... | Let | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Let'

    @staticmethod
    def to_json() -> Any:
        return 'Let'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Mutable:
    """Original type: keyword_attribute = [ ... | Mutable | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Mutable'

    @staticmethod
    def to_json() -> Any:
        return 'Mutable'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Const:
    """Original type: keyword_attribute = [ ... | Const | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Const'

    @staticmethod
    def to_json() -> Any:
        return 'Const'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Optional_:
    """Original type: keyword_attribute = [ ... | Optional | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Optional_'

    @staticmethod
    def to_json() -> Any:
        return 'Optional'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotNull:
    """Original type: keyword_attribute = [ ... | NotNull | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotNull'

    @staticmethod
    def to_json() -> Any:
        return 'NotNull'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Recursive:
    """Original type: keyword_attribute = [ ... | Recursive | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Recursive'

    @staticmethod
    def to_json() -> Any:
        return 'Recursive'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class MutuallyRecursive:
    """Original type: keyword_attribute = [ ... | MutuallyRecursive | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'MutuallyRecursive'

    @staticmethod
    def to_json() -> Any:
        return 'MutuallyRecursive'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Generator:
    """Original type: keyword_attribute = [ ... | Generator | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Generator'

    @staticmethod
    def to_json() -> Any:
        return 'Generator'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Async:
    """Original type: keyword_attribute = [ ... | Async | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Async'

    @staticmethod
    def to_json() -> Any:
        return 'Async'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Inline:
    """Original type: keyword_attribute = [ ... | Inline | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Inline'

    @staticmethod
    def to_json() -> Any:
        return 'Inline'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ctor:
    """Original type: keyword_attribute = [ ... | Ctor | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ctor'

    @staticmethod
    def to_json() -> Any:
        return 'Ctor'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Dtor:
    """Original type: keyword_attribute = [ ... | Dtor | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Dtor'

    @staticmethod
    def to_json() -> Any:
        return 'Dtor'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Getter:
    """Original type: keyword_attribute = [ ... | Getter | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Getter'

    @staticmethod
    def to_json() -> Any:
        return 'Getter'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Setter:
    """Original type: keyword_attribute = [ ... | Setter | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Setter'

    @staticmethod
    def to_json() -> Any:
        return 'Setter'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Unsafe:
    """Original type: keyword_attribute = [ ... | Unsafe | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Unsafe'

    @staticmethod
    def to_json() -> Any:
        return 'Unsafe'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DefaultImpl:
    """Original type: keyword_attribute = [ ... | DefaultImpl | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DefaultImpl'

    @staticmethod
    def to_json() -> Any:
        return 'DefaultImpl'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Lazy:
    """Original type: keyword_attribute = [ ... | Lazy | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Lazy'

    @staticmethod
    def to_json() -> Any:
        return 'Lazy'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Throws:
    """Original type: keyword_attribute = [ ... | Throws | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Throws'

    @staticmethod
    def to_json() -> Any:
        return 'Throws'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Rethrows:
    """Original type: keyword_attribute = [ ... | Rethrows | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Rethrows'

    @staticmethod
    def to_json() -> Any:
        return 'Rethrows'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherKeyword:
    """Original type: keyword_attribute = [ ... | OtherKeyword of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherKeyword'

    def to_json(self) -> Any:
        return ['OtherKeyword', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class KeywordAttribute:
    """Original type: keyword_attribute = [ ... ]"""

    value: Union[Static, Volatile, Extern, Public, Private, Protected, Abstract, Final, Override, RecordClass, AnnotationClass, EnumClass, SealedClass, Var, Let, Mutable, Const, Optional_, NotNull, Recursive, MutuallyRecursive, Generator, Async, Inline, Ctor, Dtor, Getter, Setter, Unsafe, DefaultImpl, Lazy, Throws, Rethrows, OtherKeyword]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'KeywordAttribute':
        if isinstance(x, str):
            if x == 'Static':
                return cls(Static())
            if x == 'Volatile':
                return cls(Volatile())
            if x == 'Extern':
                return cls(Extern())
            if x == 'Public':
                return cls(Public())
            if x == 'Private':
                return cls(Private())
            if x == 'Protected':
                return cls(Protected())
            if x == 'Abstract':
                return cls(Abstract())
            if x == 'Final':
                return cls(Final())
            if x == 'Override':
                return cls(Override())
            if x == 'RecordClass':
                return cls(RecordClass())
            if x == 'AnnotationClass':
                return cls(AnnotationClass())
            if x == 'EnumClass':
                return cls(EnumClass())
            if x == 'SealedClass':
                return cls(SealedClass())
            if x == 'Var':
                return cls(Var())
            if x == 'Let':
                return cls(Let())
            if x == 'Mutable':
                return cls(Mutable())
            if x == 'Const':
                return cls(Const())
            if x == 'Optional':
                return cls(Optional_())
            if x == 'NotNull':
                return cls(NotNull())
            if x == 'Recursive':
                return cls(Recursive())
            if x == 'MutuallyRecursive':
                return cls(MutuallyRecursive())
            if x == 'Generator':
                return cls(Generator())
            if x == 'Async':
                return cls(Async())
            if x == 'Inline':
                return cls(Inline())
            if x == 'Ctor':
                return cls(Ctor())
            if x == 'Dtor':
                return cls(Dtor())
            if x == 'Getter':
                return cls(Getter())
            if x == 'Setter':
                return cls(Setter())
            if x == 'Unsafe':
                return cls(Unsafe())
            if x == 'DefaultImpl':
                return cls(DefaultImpl())
            if x == 'Lazy':
                return cls(Lazy())
            if x == 'Throws':
                return cls(Throws())
            if x == 'Rethrows':
                return cls(Rethrows())
            _atd_bad_json('KeywordAttribute', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'OtherKeyword':
                return cls(OtherKeyword(_atd_read_string(x[1])))
            _atd_bad_json('KeywordAttribute', x)
        _atd_bad_json('KeywordAttribute', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'KeywordAttribute':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Plus:
    """Original type: operator = [ ... | Plus | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Plus'

    @staticmethod
    def to_json() -> Any:
        return 'Plus'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Minus:
    """Original type: operator = [ ... | Minus | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Minus'

    @staticmethod
    def to_json() -> Any:
        return 'Minus'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Mult:
    """Original type: operator = [ ... | Mult | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Mult'

    @staticmethod
    def to_json() -> Any:
        return 'Mult'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Div:
    """Original type: operator = [ ... | Div | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Div'

    @staticmethod
    def to_json() -> Any:
        return 'Div'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Mod:
    """Original type: operator = [ ... | Mod | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Mod'

    @staticmethod
    def to_json() -> Any:
        return 'Mod'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Pow:
    """Original type: operator = [ ... | Pow | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Pow'

    @staticmethod
    def to_json() -> Any:
        return 'Pow'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FloorDiv:
    """Original type: operator = [ ... | FloorDiv | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FloorDiv'

    @staticmethod
    def to_json() -> Any:
        return 'FloorDiv'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class MatMult:
    """Original type: operator = [ ... | MatMult | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'MatMult'

    @staticmethod
    def to_json() -> Any:
        return 'MatMult'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LSL:
    """Original type: operator = [ ... | LSL | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LSL'

    @staticmethod
    def to_json() -> Any:
        return 'LSL'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LSR:
    """Original type: operator = [ ... | LSR | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LSR'

    @staticmethod
    def to_json() -> Any:
        return 'LSR'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ASR:
    """Original type: operator = [ ... | ASR | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ASR'

    @staticmethod
    def to_json() -> Any:
        return 'ASR'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BitOr:
    """Original type: operator = [ ... | BitOr | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BitOr'

    @staticmethod
    def to_json() -> Any:
        return 'BitOr'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BitXor:
    """Original type: operator = [ ... | BitXor | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BitXor'

    @staticmethod
    def to_json() -> Any:
        return 'BitXor'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BitAnd:
    """Original type: operator = [ ... | BitAnd | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BitAnd'

    @staticmethod
    def to_json() -> Any:
        return 'BitAnd'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BitNot:
    """Original type: operator = [ ... | BitNot | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BitNot'

    @staticmethod
    def to_json() -> Any:
        return 'BitNot'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BitClear:
    """Original type: operator = [ ... | BitClear | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'BitClear'

    @staticmethod
    def to_json() -> Any:
        return 'BitClear'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class And:
    """Original type: operator = [ ... | And | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'And'

    @staticmethod
    def to_json() -> Any:
        return 'And'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Or:
    """Original type: operator = [ ... | Or | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Or'

    @staticmethod
    def to_json() -> Any:
        return 'Or'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Xor:
    """Original type: operator = [ ... | Xor | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Xor'

    @staticmethod
    def to_json() -> Any:
        return 'Xor'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Not:
    """Original type: operator = [ ... | Not | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Not'

    @staticmethod
    def to_json() -> Any:
        return 'Not'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Eq:
    """Original type: operator = [ ... | Eq | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Eq'

    @staticmethod
    def to_json() -> Any:
        return 'Eq'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotEq:
    """Original type: operator = [ ... | NotEq | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotEq'

    @staticmethod
    def to_json() -> Any:
        return 'NotEq'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PhysEq:
    """Original type: operator = [ ... | PhysEq | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PhysEq'

    @staticmethod
    def to_json() -> Any:
        return 'PhysEq'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotPhysEq:
    """Original type: operator = [ ... | NotPhysEq | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotPhysEq'

    @staticmethod
    def to_json() -> Any:
        return 'NotPhysEq'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Lt:
    """Original type: operator = [ ... | Lt | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Lt'

    @staticmethod
    def to_json() -> Any:
        return 'Lt'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LtE:
    """Original type: operator = [ ... | LtE | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LtE'

    @staticmethod
    def to_json() -> Any:
        return 'LtE'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Gt:
    """Original type: operator = [ ... | Gt | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Gt'

    @staticmethod
    def to_json() -> Any:
        return 'Gt'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class GtE:
    """Original type: operator = [ ... | GtE | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'GtE'

    @staticmethod
    def to_json() -> Any:
        return 'GtE'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cmp:
    """Original type: operator = [ ... | Cmp | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cmp'

    @staticmethod
    def to_json() -> Any:
        return 'Cmp'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Concat:
    """Original type: operator = [ ... | Concat | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Concat'

    @staticmethod
    def to_json() -> Any:
        return 'Concat'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Append:
    """Original type: operator = [ ... | Append | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Append'

    @staticmethod
    def to_json() -> Any:
        return 'Append'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class RegexpMatch:
    """Original type: operator = [ ... | RegexpMatch | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'RegexpMatch'

    @staticmethod
    def to_json() -> Any:
        return 'RegexpMatch'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotMatch:
    """Original type: operator = [ ... | NotMatch | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotMatch'

    @staticmethod
    def to_json() -> Any:
        return 'NotMatch'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Range:
    """Original type: operator = [ ... | Range | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Range'

    @staticmethod
    def to_json() -> Any:
        return 'Range'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class RangeInclusive:
    """Original type: operator = [ ... | RangeInclusive | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'RangeInclusive'

    @staticmethod
    def to_json() -> Any:
        return 'RangeInclusive'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotNullPostfix:
    """Original type: operator = [ ... | NotNullPostfix | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotNullPostfix'

    @staticmethod
    def to_json() -> Any:
        return 'NotNullPostfix'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Length:
    """Original type: operator = [ ... | Length | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Length'

    @staticmethod
    def to_json() -> Any:
        return 'Length'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Elvis:
    """Original type: operator = [ ... | Elvis | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Elvis'

    @staticmethod
    def to_json() -> Any:
        return 'Elvis'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Nullish:
    """Original type: operator = [ ... | Nullish | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Nullish'

    @staticmethod
    def to_json() -> Any:
        return 'Nullish'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class In:
    """Original type: operator = [ ... | In | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'In'

    @staticmethod
    def to_json() -> Any:
        return 'In'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotIn:
    """Original type: operator = [ ... | NotIn | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotIn'

    @staticmethod
    def to_json() -> Any:
        return 'NotIn'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Is:
    """Original type: operator = [ ... | Is | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Is'

    @staticmethod
    def to_json() -> Any:
        return 'Is'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotIs:
    """Original type: operator = [ ... | NotIs | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotIs'

    @staticmethod
    def to_json() -> Any:
        return 'NotIs'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Background:
    """Original type: operator = [ ... | Background | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Background'

    @staticmethod
    def to_json() -> Any:
        return 'Background'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Pipe:
    """Original type: operator = [ ... | Pipe | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Pipe'

    @staticmethod
    def to_json() -> Any:
        return 'Pipe'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Operator:
    """Original type: operator = [ ... ]"""

    value: Union[Plus, Minus, Mult, Div, Mod, Pow, FloorDiv, MatMult, LSL, LSR, ASR, BitOr, BitXor, BitAnd, BitNot, BitClear, And, Or, Xor, Not, Eq, NotEq, PhysEq, NotPhysEq, Lt, LtE, Gt, GtE, Cmp, Concat, Append, RegexpMatch, NotMatch, Range, RangeInclusive, NotNullPostfix, Length, Elvis, Nullish, In, NotIn, Is, NotIs, Background, Pipe]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Operator':
        if isinstance(x, str):
            if x == 'Plus':
                return cls(Plus())
            if x == 'Minus':
                return cls(Minus())
            if x == 'Mult':
                return cls(Mult())
            if x == 'Div':
                return cls(Div())
            if x == 'Mod':
                return cls(Mod())
            if x == 'Pow':
                return cls(Pow())
            if x == 'FloorDiv':
                return cls(FloorDiv())
            if x == 'MatMult':
                return cls(MatMult())
            if x == 'LSL':
                return cls(LSL())
            if x == 'LSR':
                return cls(LSR())
            if x == 'ASR':
                return cls(ASR())
            if x == 'BitOr':
                return cls(BitOr())
            if x == 'BitXor':
                return cls(BitXor())
            if x == 'BitAnd':
                return cls(BitAnd())
            if x == 'BitNot':
                return cls(BitNot())
            if x == 'BitClear':
                return cls(BitClear())
            if x == 'And':
                return cls(And())
            if x == 'Or':
                return cls(Or())
            if x == 'Xor':
                return cls(Xor())
            if x == 'Not':
                return cls(Not())
            if x == 'Eq':
                return cls(Eq())
            if x == 'NotEq':
                return cls(NotEq())
            if x == 'PhysEq':
                return cls(PhysEq())
            if x == 'NotPhysEq':
                return cls(NotPhysEq())
            if x == 'Lt':
                return cls(Lt())
            if x == 'LtE':
                return cls(LtE())
            if x == 'Gt':
                return cls(Gt())
            if x == 'GtE':
                return cls(GtE())
            if x == 'Cmp':
                return cls(Cmp())
            if x == 'Concat':
                return cls(Concat())
            if x == 'Append':
                return cls(Append())
            if x == 'RegexpMatch':
                return cls(RegexpMatch())
            if x == 'NotMatch':
                return cls(NotMatch())
            if x == 'Range':
                return cls(Range())
            if x == 'RangeInclusive':
                return cls(RangeInclusive())
            if x == 'NotNullPostfix':
                return cls(NotNullPostfix())
            if x == 'Length':
                return cls(Length())
            if x == 'Elvis':
                return cls(Elvis())
            if x == 'Nullish':
                return cls(Nullish())
            if x == 'In':
                return cls(In())
            if x == 'NotIn':
                return cls(NotIn())
            if x == 'Is':
                return cls(Is())
            if x == 'NotIs':
                return cls(NotIs())
            if x == 'Background':
                return cls(Background())
            if x == 'Pipe':
                return cls(Pipe())
            _atd_bad_json('Operator', x)
        _atd_bad_json('Operator', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Operator':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Prefix:
    """Original type: prefix_postfix = [ ... | Prefix | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Prefix'

    @staticmethod
    def to_json() -> Any:
        return 'Prefix'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Postfix:
    """Original type: prefix_postfix = [ ... | Postfix | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Postfix'

    @staticmethod
    def to_json() -> Any:
        return 'Postfix'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PrefixPostfix:
    """Original type: prefix_postfix = [ ... ]"""

    value: Union[Prefix, Postfix]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'PrefixPostfix':
        if isinstance(x, str):
            if x == 'Prefix':
                return cls(Prefix())
            if x == 'Postfix':
                return cls(Postfix())
            _atd_bad_json('PrefixPostfix', x)
        _atd_bad_json('PrefixPostfix', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'PrefixPostfix':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Sid:
    """Original type: sid"""

    value: int

    @classmethod
    def from_json(cls, x: Any) -> 'Sid':
        return cls(_atd_read_int(x))

    def to_json(self) -> Any:
        return _atd_write_int(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Sid':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class This:
    """Original type: special = [ ... | This | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'This'

    @staticmethod
    def to_json() -> Any:
        return 'This'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Super:
    """Original type: special = [ ... | Super | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Super'

    @staticmethod
    def to_json() -> Any:
        return 'Super'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Self:
    """Original type: special = [ ... | Self | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Self'

    @staticmethod
    def to_json() -> Any:
        return 'Self'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Parent:
    """Original type: special = [ ... | Parent | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Parent'

    @staticmethod
    def to_json() -> Any:
        return 'Parent'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Eval:
    """Original type: special = [ ... | Eval | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Eval'

    @staticmethod
    def to_json() -> Any:
        return 'Eval'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Typeof:
    """Original type: special = [ ... | Typeof | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Typeof'

    @staticmethod
    def to_json() -> Any:
        return 'Typeof'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Instanceof:
    """Original type: special = [ ... | Instanceof | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Instanceof'

    @staticmethod
    def to_json() -> Any:
        return 'Instanceof'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Sizeof:
    """Original type: special = [ ... | Sizeof | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Sizeof'

    @staticmethod
    def to_json() -> Any:
        return 'Sizeof'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Defined:
    """Original type: special = [ ... | Defined | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Defined'

    @staticmethod
    def to_json() -> Any:
        return 'Defined'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ConcatString:
    """Original type: special = [ ... | ConcatString of ... | ... ]"""

    value: ConcatStringKind

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ConcatString'

    def to_json(self) -> Any:
        return ['ConcatString', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EncodedString:
    """Original type: special = [ ... | EncodedString of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EncodedString'

    def to_json(self) -> Any:
        return ['EncodedString', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class InterpolatedElement:
    """Original type: special = [ ... | InterpolatedElement | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'InterpolatedElement'

    @staticmethod
    def to_json() -> Any:
        return 'InterpolatedElement'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Spread:
    """Original type: special = [ ... | Spread | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Spread'

    @staticmethod
    def to_json() -> Any:
        return 'Spread'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class HashSplat:
    """Original type: special = [ ... | HashSplat | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'HashSplat'

    @staticmethod
    def to_json() -> Any:
        return 'HashSplat'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForOf:
    """Original type: special = [ ... | ForOf | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForOf'

    @staticmethod
    def to_json() -> Any:
        return 'ForOf'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Op:
    """Original type: special = [ ... | Op of ... | ... ]"""

    value: Operator

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Op'

    def to_json(self) -> Any:
        return ['Op', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IncrDecr_:
    """Original type: special = [ ... | IncrDecr of ... | ... ]"""

    value: Tuple[IncrDecr, PrefixPostfix]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'IncrDecr_'

    def to_json(self) -> Any:
        return ['IncrDecr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Require:
    """Original type: special = [ ... | Require | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Require'

    @staticmethod
    def to_json() -> Any:
        return 'Require'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherSpecial:
    """Original type: special = [ ... | OtherSpecial of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherSpecial'

    def to_json(self) -> Any:
        return ['OtherSpecial', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Special:
    """Original type: special = [ ... ]"""

    value: Union[This, Super, Self, Parent, Eval, Typeof, Instanceof, Sizeof, Defined, ConcatString, EncodedString, InterpolatedElement, Spread, HashSplat, ForOf, Op, IncrDecr_, Require, OtherSpecial]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Special':
        if isinstance(x, str):
            if x == 'This':
                return cls(This())
            if x == 'Super':
                return cls(Super())
            if x == 'Self':
                return cls(Self())
            if x == 'Parent':
                return cls(Parent())
            if x == 'Eval':
                return cls(Eval())
            if x == 'Typeof':
                return cls(Typeof())
            if x == 'Instanceof':
                return cls(Instanceof())
            if x == 'Sizeof':
                return cls(Sizeof())
            if x == 'Defined':
                return cls(Defined())
            if x == 'InterpolatedElement':
                return cls(InterpolatedElement())
            if x == 'Spread':
                return cls(Spread())
            if x == 'HashSplat':
                return cls(HashSplat())
            if x == 'ForOf':
                return cls(ForOf())
            if x == 'Require':
                return cls(Require())
            _atd_bad_json('Special', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ConcatString':
                return cls(ConcatString(ConcatStringKind.from_json(x[1])))
            if cons == 'EncodedString':
                return cls(EncodedString(_atd_read_string(x[1])))
            if cons == 'Op':
                return cls(Op(Operator.from_json(x[1])))
            if cons == 'IncrDecr':
                return cls(IncrDecr_((lambda x: (IncrDecr.from_json(x[0]), PrefixPostfix.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherSpecial':
                return cls(OtherSpecial(_atd_read_string(x[1])))
            _atd_bad_json('Special', x)
        _atd_bad_json('Special', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Special':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TokenLocation:
    """Original type: token_location = { ... }"""

    str: str
    charpos: int
    line: int
    column: int
    filename: str

    @classmethod
    def from_json(cls, x: Any) -> 'TokenLocation':
        if isinstance(x, dict):
            return cls(
                str=_atd_read_string(x['str']) if 'str' in x else _atd_missing_json_field('TokenLocation', 'str'),
                charpos=_atd_read_int(x['charpos']) if 'charpos' in x else _atd_missing_json_field('TokenLocation', 'charpos'),
                line=_atd_read_int(x['line']) if 'line' in x else _atd_missing_json_field('TokenLocation', 'line'),
                column=_atd_read_int(x['column']) if 'column' in x else _atd_missing_json_field('TokenLocation', 'column'),
                filename=_atd_read_string(x['filename']) if 'filename' in x else _atd_missing_json_field('TokenLocation', 'filename'),
            )
        else:
            _atd_bad_json('TokenLocation', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['str'] = _atd_write_string(self.str)
        res['charpos'] = _atd_write_int(self.charpos)
        res['line'] = _atd_write_int(self.line)
        res['column'] = _atd_write_int(self.column)
        res['filename'] = _atd_write_string(self.filename)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'TokenLocation':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OriginTok:
    """Original type: token = [ ... | OriginTok of ... | ... ]"""

    value: TokenLocation

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OriginTok'

    def to_json(self) -> Any:
        return ['OriginTok', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FakeTok:
    """Original type: token = [ ... | FakeTok of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FakeTok'

    def to_json(self) -> Any:
        return ['FakeTok', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Token:
    """Original type: token = [ ... ]"""

    value: Union[OriginTok, FakeTok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Token':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'OriginTok':
                return cls(OriginTok(TokenLocation.from_json(x[1])))
            if cons == 'FakeTok':
                return cls(FakeTok(_atd_read_string(x[1])))
            _atd_bad_json('Token', x)
        _atd_bad_json('Token', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Token':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Tok:
    """Original type: tok"""

    value: Token

    @classmethod
    def from_json(cls, x: Any) -> 'Tok':
        return cls(Token.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Tok':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class BoolWrap:
    """Original type: _bool_wrap"""

    value: Tuple[bool, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'BoolWrap':
        return cls((lambda x: (_atd_read_bool(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [_atd_write_bool(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'BoolWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ClassKindWrap:
    """Original type: _class_kind_wrap"""

    value: Tuple[ClassKind, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ClassKindWrap':
        return cls((lambda x: (ClassKind.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ClassKindWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FloatNullableWrap:
    """Original type: _float_nullable_wrap"""

    value: Tuple[Optional[float], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'FloatNullableWrap':
        return cls((lambda x: (_atd_read_nullable(_atd_read_float)(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [_atd_write_nullable(_atd_write_float)(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'FloatNullableWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FunctionKindWrap:
    """Original type: _function_kind_wrap"""

    value: Tuple[FunctionKind, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'FunctionKindWrap':
        return cls((lambda x: (FunctionKind.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'FunctionKindWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IntNullableWrap:
    """Original type: _int_nullable_wrap"""

    value: Tuple[Optional[int], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'IntNullableWrap':
        return cls((lambda x: (_atd_read_nullable(_atd_read_int)(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [_atd_write_nullable(_atd_write_int)(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'IntNullableWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IntWrap:
    """Original type: _int_wrap"""

    value: Tuple[int, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'IntWrap':
        return cls((lambda x: (_atd_read_int(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [_atd_write_int(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'IntWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class KeywordAttributeWrap:
    """Original type: _keyword_attribute_wrap"""

    value: Tuple[KeywordAttribute, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'KeywordAttributeWrap':
        return cls((lambda x: (KeywordAttribute.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'KeywordAttributeWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OperatorWrap:
    """Original type: _operator_wrap"""

    value: Tuple[Operator, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'OperatorWrap':
        return cls((lambda x: (Operator.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'OperatorWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class SpecialWrap:
    """Original type: _special_wrap"""

    value: Tuple[Special, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'SpecialWrap':
        return cls((lambda x: (Special.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'SpecialWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class StringWrap:
    """Original type: _string_wrap"""

    value: Tuple[str, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'StringWrap':
        return cls((lambda x: (_atd_read_string(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [_atd_write_string(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'StringWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class StringWrapBracket:
    """Original type: _string_wrap_bracket"""

    value: Tuple[Tok, StringWrap, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'StringWrapBracket':
        return cls((lambda x: (Tok.from_json(x[0]), StringWrap.from_json(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'StringWrapBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ident:
    """Original type: ident"""

    value: StringWrap

    @classmethod
    def from_json(cls, x: Any) -> 'Ident':
        return cls(StringWrap.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Ident':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DottedIdent:
    """Original type: dotted_ident"""

    value: List[Ident]

    @classmethod
    def from_json(cls, x: Any) -> 'DottedIdent':
        return cls(_atd_read_list(Ident.from_json)(x))

    def to_json(self) -> Any:
        return _atd_write_list((lambda x: x.to_json()))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'DottedIdent':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Label:
    """Original type: label"""

    value: Ident

    @classmethod
    def from_json(cls, x: Any) -> 'Label':
        return cls(Ident.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Label':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Bool:
    """Original type: literal = [ ... | Bool of ... | ... ]"""

    value: BoolWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Bool'

    def to_json(self) -> Any:
        return ['Bool', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Int:
    """Original type: literal = [ ... | Int of ... | ... ]"""

    value: IntNullableWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Int'

    def to_json(self) -> Any:
        return ['Int', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Float:
    """Original type: literal = [ ... | Float of ... | ... ]"""

    value: FloatNullableWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Float'

    def to_json(self) -> Any:
        return ['Float', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Char:
    """Original type: literal = [ ... | Char of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Char'

    def to_json(self) -> Any:
        return ['Char', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class String:
    """Original type: literal = [ ... | String of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'String'

    def to_json(self) -> Any:
        return ['String', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Regexp:
    """Original type: literal = [ ... | Regexp of ... | ... ]"""

    value: Tuple[StringWrapBracket, Optional[StringWrap]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Regexp'

    def to_json(self) -> Any:
        return ['Regexp', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Atom:
    """Original type: literal = [ ... | Atom of ... | ... ]"""

    value: Tuple[Tok, StringWrap]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Atom'

    def to_json(self) -> Any:
        return ['Atom', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Unit:
    """Original type: literal = [ ... | Unit of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Unit'

    def to_json(self) -> Any:
        return ['Unit', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Null:
    """Original type: literal = [ ... | Null of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Null'

    def to_json(self) -> Any:
        return ['Null', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Undefined:
    """Original type: literal = [ ... | Undefined of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Undefined'

    def to_json(self) -> Any:
        return ['Undefined', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Imag:
    """Original type: literal = [ ... | Imag of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Imag'

    def to_json(self) -> Any:
        return ['Imag', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ratio:
    """Original type: literal = [ ... | Ratio of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ratio'

    def to_json(self) -> Any:
        return ['Ratio', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Literal:
    """Original type: literal = [ ... ]"""

    value: Union[Bool, Int, Float, Char, String, Regexp, Atom, Unit, Null, Undefined, Imag, Ratio]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Literal':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Bool':
                return cls(Bool(BoolWrap.from_json(x[1])))
            if cons == 'Int':
                return cls(Int(IntNullableWrap.from_json(x[1])))
            if cons == 'Float':
                return cls(Float(FloatNullableWrap.from_json(x[1])))
            if cons == 'Char':
                return cls(Char(StringWrap.from_json(x[1])))
            if cons == 'String':
                return cls(String(StringWrap.from_json(x[1])))
            if cons == 'Regexp':
                return cls(Regexp((lambda x: (StringWrapBracket.from_json(x[0]), _atd_read_nullable(StringWrap.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Atom':
                return cls(Atom((lambda x: (Tok.from_json(x[0]), StringWrap.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Unit':
                return cls(Unit(Tok.from_json(x[1])))
            if cons == 'Null':
                return cls(Null(Tok.from_json(x[1])))
            if cons == 'Undefined':
                return cls(Undefined(Tok.from_json(x[1])))
            if cons == 'Imag':
                return cls(Imag(StringWrap.from_json(x[1])))
            if cons == 'Ratio':
                return cls(Ratio(StringWrap.from_json(x[1])))
            _atd_bad_json('Literal', x)
        _atd_bad_json('Literal', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Literal':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DottedName:
    """Original type: module_name = [ ... | DottedName of ... | ... ]"""

    value: DottedIdent

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DottedName'

    def to_json(self) -> Any:
        return ['DottedName', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FileName:
    """Original type: module_name = [ ... | FileName of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FileName'

    def to_json(self) -> Any:
        return ['FileName', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ModuleName:
    """Original type: module_name = [ ... ]"""

    value: Union[DottedName, FileName]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ModuleName':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'DottedName':
                return cls(DottedName(DottedIdent.from_json(x[1])))
            if cons == 'FileName':
                return cls(FileName(StringWrap.from_json(x[1])))
            _atd_bad_json('ModuleName', x)
        _atd_bad_json('ModuleName', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ModuleName':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Global:
    """Original type: resolved_name_kind = [ ... | Global | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Global'

    @staticmethod
    def to_json() -> Any:
        return 'Global'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Local:
    """Original type: resolved_name_kind = [ ... | Local | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Local'

    @staticmethod
    def to_json() -> Any:
        return 'Local'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Param:
    """Original type: resolved_name_kind = [ ... | Param | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Param'

    @staticmethod
    def to_json() -> Any:
        return 'Param'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ImportedEntity:
    """Original type: resolved_name_kind = [ ... | ImportedEntity of ... | ... ]"""

    value: DottedIdent

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ImportedEntity'

    def to_json(self) -> Any:
        return ['ImportedEntity', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ImportedModule:
    """Original type: resolved_name_kind = [ ... | ImportedModule of ... | ... ]"""

    value: ModuleName

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ImportedModule'

    def to_json(self) -> Any:
        return ['ImportedModule', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherResolvedNameKind:
    """Original type: resolved_name_kind = [ ... | OtherResolvedNameKind of ... | ... ]"""

    value: str

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherResolvedNameKind'

    def to_json(self) -> Any:
        return ['OtherResolvedNameKind', _atd_write_string(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ResolvedNameKind:
    """Original type: resolved_name_kind = [ ... ]"""

    value: Union[Global, Local, Param, ImportedEntity, ImportedModule, OtherResolvedNameKind]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ResolvedNameKind':
        if isinstance(x, str):
            if x == 'Global':
                return cls(Global())
            if x == 'Local':
                return cls(Local())
            if x == 'Param':
                return cls(Param())
            _atd_bad_json('ResolvedNameKind', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ImportedEntity':
                return cls(ImportedEntity(DottedIdent.from_json(x[1])))
            if cons == 'ImportedModule':
                return cls(ImportedModule(ModuleName.from_json(x[1])))
            if cons == 'OtherResolvedNameKind':
                return cls(OtherResolvedNameKind(_atd_read_string(x[1])))
            _atd_bad_json('ResolvedNameKind', x)
        _atd_bad_json('ResolvedNameKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ResolvedNameKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ResolvedName:
    """Original type: resolved_name"""

    value: Tuple[ResolvedNameKind, Sid]

    @classmethod
    def from_json(cls, x: Any) -> 'ResolvedName':
        return cls((lambda x: (ResolvedNameKind.from_json(x[0]), Sid.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ResolvedName':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Sc:
    """Original type: sc"""

    value: Tok

    @classmethod
    def from_json(cls, x: Any) -> 'Sc':
        return cls(Tok.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Sc':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TodoKind:
    """Original type: todo_kind"""

    value: StringWrap

    @classmethod
    def from_json(cls, x: Any) -> 'TodoKind':
        return cls(StringWrap.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'TodoKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Covariant:
    """Original type: variance = [ ... | Covariant | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Covariant'

    @staticmethod
    def to_json() -> Any:
        return 'Covariant'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Contravariant:
    """Original type: variance = [ ... | Contravariant | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Contravariant'

    @staticmethod
    def to_json() -> Any:
        return 'Contravariant'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Variance:
    """Original type: variance = [ ... ]"""

    value: Union[Covariant, Contravariant]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Variance':
        if isinstance(x, str):
            if x == 'Covariant':
                return cls(Covariant())
            if x == 'Contravariant':
                return cls(Contravariant())
            _atd_bad_json('Variance', x)
        _atd_bad_json('Variance', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Variance':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class VarianceWrap:
    """Original type: _variance_wrap"""

    value: Tuple[Variance, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'VarianceWrap':
        return cls((lambda x: (Variance.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'VarianceWrap':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlClassic:
    """Original type: xml_kind = [ ... | XmlClassic of ... | ... ]"""

    value: Tuple[Tok, Ident, Tok, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlClassic'

    def to_json(self) -> Any:
        return ['XmlClassic', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2]), (lambda x: x.to_json())(x[3])] if isinstance(x, tuple) and len(x) == 4 else _atd_bad_python('tuple of length 4', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlSingleton:
    """Original type: xml_kind = [ ... | XmlSingleton of ... | ... ]"""

    value: Tuple[Tok, Ident, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlSingleton'

    def to_json(self) -> Any:
        return ['XmlSingleton', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlFragment:
    """Original type: xml_kind = [ ... | XmlFragment of ... | ... ]"""

    value: Tuple[Tok, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlFragment'

    def to_json(self) -> Any:
        return ['XmlFragment', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlKind:
    """Original type: xml_kind = [ ... ]"""

    value: Union[XmlClassic, XmlSingleton, XmlFragment]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'XmlKind':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'XmlClassic':
                return cls(XmlClassic((lambda x: (Tok.from_json(x[0]), Ident.from_json(x[1]), Tok.from_json(x[2]), Tok.from_json(x[3])) if isinstance(x, list) and len(x) == 4 else _atd_bad_json('array of length 4', x))(x[1])))
            if cons == 'XmlSingleton':
                return cls(XmlSingleton((lambda x: (Tok.from_json(x[0]), Ident.from_json(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'XmlFragment':
                return cls(XmlFragment((lambda x: (Tok.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('XmlKind', x)
        _atd_bad_json('XmlKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'XmlKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ArgumentListBracket:
    """Original type: _argument_list_bracket"""

    value: Tuple[Tok, List[Argument], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ArgumentListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Argument.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ArgumentListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Bracket0ecc50b:
    """Original type: _bracket_0ecc50b"""

    value: Tuple[Tok, Tuple[Optional[Expr], Optional[Expr], Optional[Expr]], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'Bracket0ecc50b':
        return cls((lambda x: (Tok.from_json(x[0]), (lambda x: (_atd_read_nullable(Expr.from_json)(x[0]), _atd_read_nullable(Expr.from_json)(x[1]), _atd_read_nullable(Expr.from_json)(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: [_atd_write_nullable((lambda x: x.to_json()))(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), _atd_write_nullable((lambda x: x.to_json()))(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Bracket0ecc50b':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ComprehensionBracket:
    """Original type: _comprehension_bracket"""

    value: Tuple[Tok, Comprehension, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ComprehensionBracket':
        return cls((lambda x: (Tok.from_json(x[0]), Comprehension.from_json(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ComprehensionBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class DottedIdentPatternListBracket:
    """Original type: _dotted_ident_pattern_list_bracket"""

    value: Tuple[Tok, List[Tuple[DottedIdent, Pattern]], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'DottedIdentPatternListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list((lambda x: (DottedIdent.from_json(x[0]), Pattern.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x)))(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x)))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'DottedIdentPatternListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ExprBracket:
    """Original type: _expr_bracket"""

    value: Tuple[Tok, Expr, Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ExprBracket':
        return cls((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ExprBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ExprListBracket:
    """Original type: _expr_list_bracket"""

    value: Tuple[Tok, List[Expr], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ExprListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Expr.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ExprListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ExprNullableBracket:
    """Original type: _expr_nullable_bracket"""

    value: Tuple[Tok, Optional[Expr], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'ExprNullableBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_nullable(Expr.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ExprNullableBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FieldListBracket:
    """Original type: _field_list_bracket"""

    value: Tuple[Tok, List[Field], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'FieldListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Field.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'FieldListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class PatternListBracket:
    """Original type: _pattern_list_bracket"""

    value: Tuple[Tok, List[Pattern], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'PatternListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Pattern.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'PatternListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class StmtListBracket:
    """Original type: _stmt_list_bracket"""

    value: Tuple[Tok, List[Stmt], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'StmtListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Stmt.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'StmtListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeArgumentListBracket:
    """Original type: _type_argument_list_bracket"""

    value: Tuple[Tok, List[TypeArgument], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'TypeArgumentListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(TypeArgument.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeArgumentListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeListBracket:
    """Original type: _type_list_bracket"""

    value: Tuple[Tok, List[Type], Tok]

    @classmethod
    def from_json(cls, x: Any) -> 'TypeListBracket':
        return cls((lambda x: (Tok.from_json(x[0]), _atd_read_list(Type.from_json)(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeListBracket':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Alias:
    """Original type: alias"""

    value: Tuple[Ident, IdInfo]

    @classmethod
    def from_json(cls, x: Any) -> 'Alias':
        return cls((lambda x: (Ident.from_json(x[0]), IdInfo.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Alias':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class E:
    """Original type: any = [ ... | E of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'E'

    def to_json(self) -> Any:
        return ['E', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class S:
    """Original type: any = [ ... | S of ... | ... ]"""

    value: Stmt

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'S'

    def to_json(self) -> Any:
        return ['S', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class T:
    """Original type: any = [ ... | T of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'T'

    def to_json(self) -> Any:
        return ['T', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class P:
    """Original type: any = [ ... | P of ... | ... ]"""

    value: Pattern

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'P'

    def to_json(self) -> Any:
        return ['P', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class At:
    """Original type: any = [ ... | At of ... | ... ]"""

    value: Attribute

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'At'

    def to_json(self) -> Any:
        return ['At', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Fld:
    """Original type: any = [ ... | Fld of ... | ... ]"""

    value: Field

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Fld'

    def to_json(self) -> Any:
        return ['Fld', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ar:
    """Original type: any = [ ... | Ar of ... | ... ]"""

    value: Argument

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ar'

    def to_json(self) -> Any:
        return ['Ar', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Pa:
    """Original type: any = [ ... | Pa of ... | ... ]"""

    value: Parameter

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Pa'

    def to_json(self) -> Any:
        return ['Pa', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ta:
    """Original type: any = [ ... | Ta of ... | ... ]"""

    value: TypeArgument

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ta'

    def to_json(self) -> Any:
        return ['Ta', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Tp:
    """Original type: any = [ ... | Tp of ... | ... ]"""

    value: TypeParameter

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Tp'

    def to_json(self) -> Any:
        return ['Tp', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ce:
    """Original type: any = [ ... | Ce of ... | ... ]"""

    value: CatchExn

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ce'

    def to_json(self) -> Any:
        return ['Ce', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cs:
    """Original type: any = [ ... | Cs of ... | ... ]"""

    value: Case

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cs'

    def to_json(self) -> Any:
        return ['Cs', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForOrIfComp_:
    """Original type: any = [ ... | ForOrIfComp of ... | ... ]"""

    value: ForOrIfComp

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForOrIfComp_'

    def to_json(self) -> Any:
        return ['ForOrIfComp', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class En:
    """Original type: any = [ ... | En of ... | ... ]"""

    value: Entity

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'En'

    def to_json(self) -> Any:
        return ['En', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class I:
    """Original type: any = [ ... | I of ... | ... ]"""

    value: Ident

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'I'

    def to_json(self) -> Any:
        return ['I', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Modn:
    """Original type: any = [ ... | Modn of ... | ... ]"""

    value: ModuleName

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Modn'

    def to_json(self) -> Any:
        return ['Modn', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Di:
    """Original type: any = [ ... | Di of ... | ... ]"""

    value: DottedIdent

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Di'

    def to_json(self) -> Any:
        return ['Di', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Lbli:
    """Original type: any = [ ... | Lbli of ... | ... ]"""

    value: LabelIdent

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Lbli'

    def to_json(self) -> Any:
        return ['Lbli', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Str:
    """Original type: any = [ ... | Str of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Str'

    def to_json(self) -> Any:
        return ['Str', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Tk:
    """Original type: any = [ ... | Tk of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Tk'

    def to_json(self) -> Any:
        return ['Tk', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TodoK:
    """Original type: any = [ ... | TodoK of ... | ... ]"""

    value: TodoKind

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TodoK'

    def to_json(self) -> Any:
        return ['TodoK', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Anys:
    """Original type: any = [ ... | Anys of ... | ... ]"""

    value: Tuple[List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Anys'

    def to_json(self) -> Any:
        return ['Anys', (lambda x: [_atd_write_list((lambda x: x.to_json()))(x[0])] if isinstance(x, tuple) and len(x) == 1 else _atd_bad_python('tuple of length 1', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Any_:
    """Original type: any = [ ... ]"""

    value: Union[E, S, T, P, At, Fld, Ar, Pa, Ta, Tp, Ce, Cs, ForOrIfComp_, En, I, Modn, Di, Lbli, Str, Tk, TodoK, Anys]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Any_':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'E':
                return cls(E(Expr.from_json(x[1])))
            if cons == 'S':
                return cls(S(Stmt.from_json(x[1])))
            if cons == 'T':
                return cls(T(Type.from_json(x[1])))
            if cons == 'P':
                return cls(P(Pattern.from_json(x[1])))
            if cons == 'At':
                return cls(At(Attribute.from_json(x[1])))
            if cons == 'Fld':
                return cls(Fld(Field.from_json(x[1])))
            if cons == 'Ar':
                return cls(Ar(Argument.from_json(x[1])))
            if cons == 'Pa':
                return cls(Pa(Parameter.from_json(x[1])))
            if cons == 'Ta':
                return cls(Ta(TypeArgument.from_json(x[1])))
            if cons == 'Tp':
                return cls(Tp(TypeParameter.from_json(x[1])))
            if cons == 'Ce':
                return cls(Ce(CatchExn.from_json(x[1])))
            if cons == 'Cs':
                return cls(Cs(Case.from_json(x[1])))
            if cons == 'ForOrIfComp':
                return cls(ForOrIfComp_(ForOrIfComp.from_json(x[1])))
            if cons == 'En':
                return cls(En(Entity.from_json(x[1])))
            if cons == 'I':
                return cls(I(Ident.from_json(x[1])))
            if cons == 'Modn':
                return cls(Modn(ModuleName.from_json(x[1])))
            if cons == 'Di':
                return cls(Di(DottedIdent.from_json(x[1])))
            if cons == 'Lbli':
                return cls(Lbli(LabelIdent.from_json(x[1])))
            if cons == 'Str':
                return cls(Str(StringWrap.from_json(x[1])))
            if cons == 'Tk':
                return cls(Tk(Tok.from_json(x[1])))
            if cons == 'TodoK':
                return cls(TodoK(TodoKind.from_json(x[1])))
            if cons == 'Anys':
                return cls(Anys((lambda x: (_atd_read_list(Any_.from_json)(x[0])) if isinstance(x, list) and len(x) == 1 else _atd_bad_json('array of length 1', x))(x[1])))
            _atd_bad_json('Any_', x)
        _atd_bad_json('Any_', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Any_':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Arg:
    """Original type: argument = [ ... | Arg of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Arg'

    def to_json(self) -> Any:
        return ['Arg', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ArgKwd:
    """Original type: argument = [ ... | ArgKwd of ... | ... ]"""

    value: Tuple[Ident, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ArgKwd'

    def to_json(self) -> Any:
        return ['ArgKwd', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ArgKwdOptional:
    """Original type: argument = [ ... | ArgKwdOptional of ... | ... ]"""

    value: Tuple[Ident, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ArgKwdOptional'

    def to_json(self) -> Any:
        return ['ArgKwdOptional', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ArgType:
    """Original type: argument = [ ... | ArgType of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ArgType'

    def to_json(self) -> Any:
        return ['ArgType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherArg:
    """Original type: argument = [ ... | OtherArg of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherArg'

    def to_json(self) -> Any:
        return ['OtherArg', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Argument:
    """Original type: argument = [ ... ]"""

    value: Union[Arg, ArgKwd, ArgKwdOptional, ArgType, OtherArg]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Argument':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Arg':
                return cls(Arg(Expr.from_json(x[1])))
            if cons == 'ArgKwd':
                return cls(ArgKwd((lambda x: (Ident.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'ArgKwdOptional':
                return cls(ArgKwdOptional((lambda x: (Ident.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'ArgType':
                return cls(ArgType(Type.from_json(x[1])))
            if cons == 'OtherArg':
                return cls(OtherArg((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Argument', x)
        _atd_bad_json('Argument', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Argument':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Arguments:
    """Original type: arguments"""

    value: ArgumentListBracket

    @classmethod
    def from_json(cls, x: Any) -> 'Arguments':
        return cls(ArgumentListBracket.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Arguments':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class KeywordAttr:
    """Original type: attribute = [ ... | KeywordAttr of ... | ... ]"""

    value: KeywordAttributeWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'KeywordAttr'

    def to_json(self) -> Any:
        return ['KeywordAttr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NamedAttr:
    """Original type: attribute = [ ... | NamedAttr of ... | ... ]"""

    value: Tuple[Tok, Name, Arguments]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NamedAttr'

    def to_json(self) -> Any:
        return ['NamedAttr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherAttribute:
    """Original type: attribute = [ ... | OtherAttribute of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherAttribute'

    def to_json(self) -> Any:
        return ['OtherAttribute', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Attribute:
    """Original type: attribute = [ ... ]"""

    value: Union[KeywordAttr, NamedAttr, OtherAttribute]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Attribute':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'KeywordAttr':
                return cls(KeywordAttr(KeywordAttributeWrap.from_json(x[1])))
            if cons == 'NamedAttr':
                return cls(NamedAttr((lambda x: (Tok.from_json(x[0]), Name.from_json(x[1]), Arguments.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'OtherAttribute':
                return cls(OtherAttribute((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Attribute', x)
        _atd_bad_json('Attribute', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Attribute':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Case_:
    """Original type: case = [ ... | Case of ... | ... ]"""

    value: Tuple[Tok, Pattern]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Case_'

    def to_json(self) -> Any:
        return ['Case', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Default:
    """Original type: case = [ ... | Default of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Default'

    def to_json(self) -> Any:
        return ['Default', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class CaseEqualExpr:
    """Original type: case = [ ... | CaseEqualExpr of ... | ... ]"""

    value: Tuple[Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CaseEqualExpr'

    def to_json(self) -> Any:
        return ['CaseEqualExpr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherCase:
    """Original type: case = [ ... | OtherCase of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherCase'

    def to_json(self) -> Any:
        return ['OtherCase', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Case:
    """Original type: case = [ ... ]"""

    value: Union[Case_, Default, CaseEqualExpr, OtherCase]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Case':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Case':
                return cls(Case_((lambda x: (Tok.from_json(x[0]), Pattern.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Default':
                return cls(Default(Tok.from_json(x[1])))
            if cons == 'CaseEqualExpr':
                return cls(CaseEqualExpr((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherCase':
                return cls(OtherCase((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Case', x)
        _atd_bad_json('Case', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Case':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class CasesAndBody:
    """Original type: case_and_body = [ ... | CasesAndBody of ... | ... ]"""

    value: Tuple[List[Case], Stmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CasesAndBody'

    def to_json(self) -> Any:
        return ['CasesAndBody', (lambda x: [_atd_write_list((lambda x: x.to_json()))(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class CaseAndBody:
    """Original type: case_and_body = [ ... ]"""

    value: Union[CasesAndBody]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'CaseAndBody':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'CasesAndBody':
                return cls(CasesAndBody((lambda x: (_atd_read_list(Case.from_json)(x[0]), Stmt.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('CaseAndBody', x)
        _atd_bad_json('CaseAndBody', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'CaseAndBody':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Catch:
    """Original type: catch"""

    value: Tuple[Tok, CatchExn, Stmt]

    @classmethod
    def from_json(cls, x: Any) -> 'Catch':
        return cls((lambda x: (Tok.from_json(x[0]), CatchExn.from_json(x[1]), Stmt.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Catch':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class CatchPattern:
    """Original type: catch_exn = [ ... | CatchPattern of ... | ... ]"""

    value: Pattern

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CatchPattern'

    def to_json(self) -> Any:
        return ['CatchPattern', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class CatchParam:
    """Original type: catch_exn = [ ... | CatchParam of ... | ... ]"""

    value: ParameterClassic

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CatchParam'

    def to_json(self) -> Any:
        return ['CatchParam', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherCatch:
    """Original type: catch_exn = [ ... | OtherCatch of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherCatch'

    def to_json(self) -> Any:
        return ['OtherCatch', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class CatchExn:
    """Original type: catch_exn = [ ... ]"""

    value: Union[CatchPattern, CatchParam, OtherCatch]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'CatchExn':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'CatchPattern':
                return cls(CatchPattern(Pattern.from_json(x[1])))
            if cons == 'CatchParam':
                return cls(CatchParam(ParameterClassic.from_json(x[1])))
            if cons == 'OtherCatch':
                return cls(OtherCatch((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('CatchExn', x)
        _atd_bad_json('CatchExn', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'CatchExn':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ClassDefinition:
    """Original type: class_definition = { ... }"""

    ckind: ClassKindWrap
    cextends: List[ClassParent]
    cimplements: List[Type]
    cmixins: List[Type]
    cparams: Parameters
    cbody: FieldListBracket

    @classmethod
    def from_json(cls, x: Any) -> 'ClassDefinition':
        if isinstance(x, dict):
            return cls(
                ckind=ClassKindWrap.from_json(x['ckind']) if 'ckind' in x else _atd_missing_json_field('ClassDefinition', 'ckind'),
                cextends=_atd_read_list(ClassParent.from_json)(x['cextends']) if 'cextends' in x else _atd_missing_json_field('ClassDefinition', 'cextends'),
                cimplements=_atd_read_list(Type.from_json)(x['cimplements']) if 'cimplements' in x else _atd_missing_json_field('ClassDefinition', 'cimplements'),
                cmixins=_atd_read_list(Type.from_json)(x['cmixins']) if 'cmixins' in x else _atd_missing_json_field('ClassDefinition', 'cmixins'),
                cparams=Parameters.from_json(x['cparams']) if 'cparams' in x else _atd_missing_json_field('ClassDefinition', 'cparams'),
                cbody=FieldListBracket.from_json(x['cbody']) if 'cbody' in x else _atd_missing_json_field('ClassDefinition', 'cbody'),
            )
        else:
            _atd_bad_json('ClassDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['ckind'] = (lambda x: x.to_json())(self.ckind)
        res['cextends'] = _atd_write_list((lambda x: x.to_json()))(self.cextends)
        res['cimplements'] = _atd_write_list((lambda x: x.to_json()))(self.cimplements)
        res['cmixins'] = _atd_write_list((lambda x: x.to_json()))(self.cmixins)
        res['cparams'] = (lambda x: x.to_json())(self.cparams)
        res['cbody'] = (lambda x: x.to_json())(self.cbody)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'ClassDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ClassParent:
    """Original type: class_parent"""

    value: Tuple[Type, Optional[Arguments]]

    @classmethod
    def from_json(cls, x: Any) -> 'ClassParent':
        return cls((lambda x: (Type.from_json(x[0]), _atd_read_nullable(Arguments.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ClassParent':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Comprehension:
    """Original type: comprehension"""

    value: Tuple[Expr, List[ForOrIfComp]]

    @classmethod
    def from_json(cls, x: Any) -> 'Comprehension':
        return cls((lambda x: (Expr.from_json(x[0]), _atd_read_list(ForOrIfComp.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Comprehension':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Cond:
    """Original type: condition = [ ... | Cond of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cond'

    def to_json(self) -> Any:
        return ['Cond', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherCond:
    """Original type: condition = [ ... | OtherCond of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherCond'

    def to_json(self) -> Any:
        return ['OtherCond', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Condition:
    """Original type: condition = [ ... ]"""

    value: Union[Cond, OtherCond]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Condition':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Cond':
                return cls(Cond(Expr.from_json(x[1])))
            if cons == 'OtherCond':
                return cls(OtherCond((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Condition', x)
        _atd_bad_json('Condition', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Condition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Definition:
    """Original type: definition"""

    value: Tuple[Entity, DefinitionKind]

    @classmethod
    def from_json(cls, x: Any) -> 'Definition':
        return cls((lambda x: (Entity.from_json(x[0]), DefinitionKind.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Definition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FuncDef:
    """Original type: definition_kind = [ ... | FuncDef of ... | ... ]"""

    value: FunctionDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FuncDef'

    def to_json(self) -> Any:
        return ['FuncDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class VarDef:
    """Original type: definition_kind = [ ... | VarDef of ... | ... ]"""

    value: VariableDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'VarDef'

    def to_json(self) -> Any:
        return ['VarDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ClassDef:
    """Original type: definition_kind = [ ... | ClassDef of ... | ... ]"""

    value: ClassDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ClassDef'

    def to_json(self) -> Any:
        return ['ClassDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EnumEntryDef:
    """Original type: definition_kind = [ ... | EnumEntryDef of ... | ... ]"""

    value: EnumEntryDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EnumEntryDef'

    def to_json(self) -> Any:
        return ['EnumEntryDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TypeDef:
    """Original type: definition_kind = [ ... | TypeDef of ... | ... ]"""

    value: TypeDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TypeDef'

    def to_json(self) -> Any:
        return ['TypeDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ModuleDef:
    """Original type: definition_kind = [ ... | ModuleDef of ... | ... ]"""

    value: ModuleDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ModuleDef'

    def to_json(self) -> Any:
        return ['ModuleDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class MacroDef:
    """Original type: definition_kind = [ ... | MacroDef of ... | ... ]"""

    value: MacroDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'MacroDef'

    def to_json(self) -> Any:
        return ['MacroDef', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Signature:
    """Original type: definition_kind = [ ... | Signature of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Signature'

    def to_json(self) -> Any:
        return ['Signature', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class UseOuterDecl:
    """Original type: definition_kind = [ ... | UseOuterDecl of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'UseOuterDecl'

    def to_json(self) -> Any:
        return ['UseOuterDecl', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherDef:
    """Original type: definition_kind = [ ... | OtherDef of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherDef'

    def to_json(self) -> Any:
        return ['OtherDef', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DefinitionKind:
    """Original type: definition_kind = [ ... ]"""

    value: Union[FuncDef, VarDef, ClassDef, EnumEntryDef, TypeDef, ModuleDef, MacroDef, Signature, UseOuterDecl, OtherDef]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'DefinitionKind':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'FuncDef':
                return cls(FuncDef(FunctionDefinition.from_json(x[1])))
            if cons == 'VarDef':
                return cls(VarDef(VariableDefinition.from_json(x[1])))
            if cons == 'ClassDef':
                return cls(ClassDef(ClassDefinition.from_json(x[1])))
            if cons == 'EnumEntryDef':
                return cls(EnumEntryDef(EnumEntryDefinition.from_json(x[1])))
            if cons == 'TypeDef':
                return cls(TypeDef(TypeDefinition.from_json(x[1])))
            if cons == 'ModuleDef':
                return cls(ModuleDef(ModuleDefinition.from_json(x[1])))
            if cons == 'MacroDef':
                return cls(MacroDef(MacroDefinition.from_json(x[1])))
            if cons == 'Signature':
                return cls(Signature(Type.from_json(x[1])))
            if cons == 'UseOuterDecl':
                return cls(UseOuterDecl(Tok.from_json(x[1])))
            if cons == 'OtherDef':
                return cls(OtherDef((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('DefinitionKind', x)
        _atd_bad_json('DefinitionKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'DefinitionKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ImportFrom:
    """Original type: directive = [ ... | ImportFrom of ... | ... ]"""

    value: Tuple[Tok, ModuleName, List[Tuple[Ident, Optional[Alias]]]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ImportFrom'

    def to_json(self) -> Any:
        return ['ImportFrom', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), _atd_write_list((lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x)))(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ImportAs:
    """Original type: directive = [ ... | ImportAs of ... | ... ]"""

    value: Tuple[Tok, ModuleName, Optional[Alias]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ImportAs'

    def to_json(self) -> Any:
        return ['ImportAs', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), _atd_write_nullable((lambda x: x.to_json()))(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ImportAll:
    """Original type: directive = [ ... | ImportAll of ... | ... ]"""

    value: Tuple[Tok, ModuleName, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ImportAll'

    def to_json(self) -> Any:
        return ['ImportAll', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Package:
    """Original type: directive = [ ... | Package of ... | ... ]"""

    value: Tuple[Tok, DottedIdent]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Package'

    def to_json(self) -> Any:
        return ['Package', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PackageEnd:
    """Original type: directive = [ ... | PackageEnd of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PackageEnd'

    def to_json(self) -> Any:
        return ['PackageEnd', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Pragma:
    """Original type: directive = [ ... | Pragma of ... | ... ]"""

    value: Tuple[Ident, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Pragma'

    def to_json(self) -> Any:
        return ['Pragma', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherDirective:
    """Original type: directive = [ ... | OtherDirective of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherDirective'

    def to_json(self) -> Any:
        return ['OtherDirective', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Directive:
    """Original type: directive = [ ... ]"""

    value: Union[ImportFrom, ImportAs, ImportAll, Package, PackageEnd, Pragma, OtherDirective]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Directive':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ImportFrom':
                return cls(ImportFrom((lambda x: (Tok.from_json(x[0]), ModuleName.from_json(x[1]), _atd_read_list((lambda x: (Ident.from_json(x[0]), _atd_read_nullable(Alias.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x)))(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'ImportAs':
                return cls(ImportAs((lambda x: (Tok.from_json(x[0]), ModuleName.from_json(x[1]), _atd_read_nullable(Alias.from_json)(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'ImportAll':
                return cls(ImportAll((lambda x: (Tok.from_json(x[0]), ModuleName.from_json(x[1]), Tok.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Package':
                return cls(Package((lambda x: (Tok.from_json(x[0]), DottedIdent.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PackageEnd':
                return cls(PackageEnd(Tok.from_json(x[1])))
            if cons == 'Pragma':
                return cls(Pragma((lambda x: (Ident.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherDirective':
                return cls(OtherDirective((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Directive', x)
        _atd_bad_json('Directive', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Directive':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Entity:
    """Original type: entity = { ... }"""

    name: EntityName
    attrs: List[Attribute]
    tparams: TypeParameters

    @classmethod
    def from_json(cls, x: Any) -> 'Entity':
        if isinstance(x, dict):
            return cls(
                name=EntityName.from_json(x['name']) if 'name' in x else _atd_missing_json_field('Entity', 'name'),
                attrs=_atd_read_list(Attribute.from_json)(x['attrs']) if 'attrs' in x else _atd_missing_json_field('Entity', 'attrs'),
                tparams=TypeParameters.from_json(x['tparams']) if 'tparams' in x else _atd_missing_json_field('Entity', 'tparams'),
            )
        else:
            _atd_bad_json('Entity', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['name'] = (lambda x: x.to_json())(self.name)
        res['attrs'] = _atd_write_list((lambda x: x.to_json()))(self.attrs)
        res['tparams'] = (lambda x: x.to_json())(self.tparams)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'Entity':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class EN:
    """Original type: entity_name = [ ... | EN of ... | ... ]"""

    value: Name

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EN'

    def to_json(self) -> Any:
        return ['EN', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EDynamic:
    """Original type: entity_name = [ ... | EDynamic of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EDynamic'

    def to_json(self) -> Any:
        return ['EDynamic', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EPattern:
    """Original type: entity_name = [ ... | EPattern of ... | ... ]"""

    value: Pattern

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'EPattern'

    def to_json(self) -> Any:
        return ['EPattern', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherEntity:
    """Original type: entity_name = [ ... | OtherEntity of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherEntity'

    def to_json(self) -> Any:
        return ['OtherEntity', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class EntityName:
    """Original type: entity_name = [ ... ]"""

    value: Union[EN, EDynamic, EPattern, OtherEntity]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'EntityName':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'EN':
                return cls(EN(Name.from_json(x[1])))
            if cons == 'EDynamic':
                return cls(EDynamic(Expr.from_json(x[1])))
            if cons == 'EPattern':
                return cls(EPattern(Pattern.from_json(x[1])))
            if cons == 'OtherEntity':
                return cls(OtherEntity((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('EntityName', x)
        _atd_bad_json('EntityName', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'EntityName':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class EnumEntryDefinition:
    """Original type: enum_entry_definition = { ... }"""

    ee_args: Optional[Arguments]
    ee_body: Optional[FieldListBracket]

    @classmethod
    def from_json(cls, x: Any) -> 'EnumEntryDefinition':
        if isinstance(x, dict):
            return cls(
                ee_args=_atd_read_nullable(Arguments.from_json)(x['ee_args']) if 'ee_args' in x else _atd_missing_json_field('EnumEntryDefinition', 'ee_args'),
                ee_body=_atd_read_nullable(FieldListBracket.from_json)(x['ee_body']) if 'ee_body' in x else _atd_missing_json_field('EnumEntryDefinition', 'ee_body'),
            )
        else:
            _atd_bad_json('EnumEntryDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['ee_args'] = _atd_write_nullable((lambda x: x.to_json()))(self.ee_args)
        res['ee_body'] = _atd_write_nullable((lambda x: x.to_json()))(self.ee_body)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'EnumEntryDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class L:
    """Original type: expr = [ ... | L of ... | ... ]"""

    value: Literal

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'L'

    def to_json(self) -> Any:
        return ['L', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Container:
    """Original type: expr = [ ... | Container of ... | ... ]"""

    value: Tuple[ContainerOperator, ExprListBracket]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Container'

    def to_json(self) -> Any:
        return ['Container', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Comprehension_:
    """Original type: expr = [ ... | Comprehension of ... | ... ]"""

    value: Tuple[ContainerOperator, ComprehensionBracket]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Comprehension_'

    def to_json(self) -> Any:
        return ['Comprehension', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Record:
    """Original type: expr = [ ... | Record of ... | ... ]"""

    value: FieldListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Record'

    def to_json(self) -> Any:
        return ['Record', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Constructor:
    """Original type: expr = [ ... | Constructor of ... | ... ]"""

    value: Tuple[Name, ExprListBracket]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Constructor'

    def to_json(self) -> Any:
        return ['Constructor', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class N:
    """Original type: expr = [ ... | N of ... | ... ]"""

    value: Name

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'N'

    def to_json(self) -> Any:
        return ['N', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IdSpecial:
    """Original type: expr = [ ... | IdSpecial of ... | ... ]"""

    value: SpecialWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'IdSpecial'

    def to_json(self) -> Any:
        return ['IdSpecial', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Call:
    """Original type: expr = [ ... | Call of ... | ... ]"""

    value: Tuple[Expr, Arguments]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Call'

    def to_json(self) -> Any:
        return ['Call', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class New:
    """Original type: expr = [ ... | New of ... | ... ]"""

    value: Tuple[Tok, Type, Arguments]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'New'

    def to_json(self) -> Any:
        return ['New', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Xml_:
    """Original type: expr = [ ... | Xml of ... | ... ]"""

    value: Xml

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Xml_'

    def to_json(self) -> Any:
        return ['Xml', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Assign:
    """Original type: expr = [ ... | Assign of ... | ... ]"""

    value: Tuple[Expr, Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Assign'

    def to_json(self) -> Any:
        return ['Assign', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AssignOp:
    """Original type: expr = [ ... | AssignOp of ... | ... ]"""

    value: Tuple[Expr, OperatorWrap, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AssignOp'

    def to_json(self) -> Any:
        return ['AssignOp', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LetPattern:
    """Original type: expr = [ ... | LetPattern of ... | ... ]"""

    value: Tuple[Pattern, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LetPattern'

    def to_json(self) -> Any:
        return ['LetPattern', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DotAccess:
    """Original type: expr = [ ... | DotAccess of ... | ... ]"""

    value: Tuple[Expr, Tok, FieldName]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DotAccess'

    def to_json(self) -> Any:
        return ['DotAccess', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ArrayAccess:
    """Original type: expr = [ ... | ArrayAccess of ... | ... ]"""

    value: Tuple[Expr, ExprBracket]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ArrayAccess'

    def to_json(self) -> Any:
        return ['ArrayAccess', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class SliceAccess:
    """Original type: expr = [ ... | SliceAccess of ... | ... ]"""

    value: Tuple[Expr, Bracket0ecc50b]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'SliceAccess'

    def to_json(self) -> Any:
        return ['SliceAccess', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Lambda:
    """Original type: expr = [ ... | Lambda of ... | ... ]"""

    value: FunctionDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Lambda'

    def to_json(self) -> Any:
        return ['Lambda', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AnonClass:
    """Original type: expr = [ ... | AnonClass of ... | ... ]"""

    value: ClassDefinition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AnonClass'

    def to_json(self) -> Any:
        return ['AnonClass', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Conditional:
    """Original type: expr = [ ... | Conditional of ... | ... ]"""

    value: Tuple[Expr, Expr, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Conditional'

    def to_json(self) -> Any:
        return ['Conditional', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Yield:
    """Original type: expr = [ ... | Yield of ... | ... ]"""

    value: Tuple[Tok, Optional[Expr], bool]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Yield'

    def to_json(self) -> Any:
        return ['Yield', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), _atd_write_bool(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Await:
    """Original type: expr = [ ... | Await of ... | ... ]"""

    value: Tuple[Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Await'

    def to_json(self) -> Any:
        return ['Await', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cast:
    """Original type: expr = [ ... | Cast of ... | ... ]"""

    value: Tuple[Type, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cast'

    def to_json(self) -> Any:
        return ['Cast', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Seq:
    """Original type: expr = [ ... | Seq of ... | ... ]"""

    value: List[Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Seq'

    def to_json(self) -> Any:
        return ['Seq', _atd_write_list((lambda x: x.to_json()))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ref:
    """Original type: expr = [ ... | Ref of ... | ... ]"""

    value: Tuple[Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ref'

    def to_json(self) -> Any:
        return ['Ref', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DeRef:
    """Original type: expr = [ ... | DeRef of ... | ... ]"""

    value: Tuple[Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DeRef'

    def to_json(self) -> Any:
        return ['DeRef', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Ellipsis:
    """Original type: expr = [ ... | Ellipsis of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Ellipsis'

    def to_json(self) -> Any:
        return ['Ellipsis', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ParenExpr:
    """Original type: expr = [ ... | ParenExpr of ... | ... ]"""

    value: ExprBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ParenExpr'

    def to_json(self) -> Any:
        return ['ParenExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class StmtExpr:
    """Original type: expr = [ ... | StmtExpr of ... | ... ]"""

    value: Stmt

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'StmtExpr'

    def to_json(self) -> Any:
        return ['StmtExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherExpr:
    """Original type: expr = [ ... | OtherExpr of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherExpr'

    def to_json(self) -> Any:
        return ['OtherExpr', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Expr:
    """Original type: expr = [ ... ]"""

    value: Union[L, Container, Comprehension_, Record, Constructor, N, IdSpecial, Call, New, Xml_, Assign, AssignOp, LetPattern, DotAccess, ArrayAccess, SliceAccess, Lambda, AnonClass, Conditional, Yield, Await, Cast, Seq, Ref, DeRef, Ellipsis, ParenExpr, StmtExpr, OtherExpr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Expr':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'L':
                return cls(L(Literal.from_json(x[1])))
            if cons == 'Container':
                return cls(Container((lambda x: (ContainerOperator.from_json(x[0]), ExprListBracket.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Comprehension':
                return cls(Comprehension_((lambda x: (ContainerOperator.from_json(x[0]), ComprehensionBracket.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Record':
                return cls(Record(FieldListBracket.from_json(x[1])))
            if cons == 'Constructor':
                return cls(Constructor((lambda x: (Name.from_json(x[0]), ExprListBracket.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'N':
                return cls(N(Name.from_json(x[1])))
            if cons == 'IdSpecial':
                return cls(IdSpecial(SpecialWrap.from_json(x[1])))
            if cons == 'Call':
                return cls(Call((lambda x: (Expr.from_json(x[0]), Arguments.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'New':
                return cls(New((lambda x: (Tok.from_json(x[0]), Type.from_json(x[1]), Arguments.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Xml':
                return cls(Xml_(Xml.from_json(x[1])))
            if cons == 'Assign':
                return cls(Assign((lambda x: (Expr.from_json(x[0]), Tok.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'AssignOp':
                return cls(AssignOp((lambda x: (Expr.from_json(x[0]), OperatorWrap.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'LetPattern':
                return cls(LetPattern((lambda x: (Pattern.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'DotAccess':
                return cls(DotAccess((lambda x: (Expr.from_json(x[0]), Tok.from_json(x[1]), FieldName.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'ArrayAccess':
                return cls(ArrayAccess((lambda x: (Expr.from_json(x[0]), ExprBracket.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'SliceAccess':
                return cls(SliceAccess((lambda x: (Expr.from_json(x[0]), Bracket0ecc50b.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Lambda':
                return cls(Lambda(FunctionDefinition.from_json(x[1])))
            if cons == 'AnonClass':
                return cls(AnonClass(ClassDefinition.from_json(x[1])))
            if cons == 'Conditional':
                return cls(Conditional((lambda x: (Expr.from_json(x[0]), Expr.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Yield':
                return cls(Yield((lambda x: (Tok.from_json(x[0]), _atd_read_nullable(Expr.from_json)(x[1]), _atd_read_bool(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Await':
                return cls(Await((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Cast':
                return cls(Cast((lambda x: (Type.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Seq':
                return cls(Seq(_atd_read_list(Expr.from_json)(x[1])))
            if cons == 'Ref':
                return cls(Ref((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'DeRef':
                return cls(DeRef((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Ellipsis':
                return cls(Ellipsis(Tok.from_json(x[1])))
            if cons == 'ParenExpr':
                return cls(ParenExpr(ExprBracket.from_json(x[1])))
            if cons == 'StmtExpr':
                return cls(StmtExpr(Stmt.from_json(x[1])))
            if cons == 'OtherExpr':
                return cls(OtherExpr((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Expr', x)
        _atd_bad_json('Expr', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Expr':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class F:
    """Original type: field = [ ... | F of ... | ... ]"""

    value: Stmt

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'F'

    def to_json(self) -> Any:
        return ['F', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Field:
    """Original type: field = [ ... ]"""

    value: Union[F]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Field':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'F':
                return cls(F(Stmt.from_json(x[1])))
            _atd_bad_json('Field', x)
        _atd_bad_json('Field', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Field':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FN:
    """Original type: field_name = [ ... | FN of ... | ... ]"""

    value: Name

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FN'

    def to_json(self) -> Any:
        return ['FN', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FDynamic:
    """Original type: field_name = [ ... | FDynamic of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FDynamic'

    def to_json(self) -> Any:
        return ['FDynamic', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FieldName:
    """Original type: field_name = [ ... ]"""

    value: Union[FN, FDynamic]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'FieldName':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'FN':
                return cls(FN(Name.from_json(x[1])))
            if cons == 'FDynamic':
                return cls(FDynamic(Expr.from_json(x[1])))
            _atd_bad_json('FieldName', x)
        _atd_bad_json('FieldName', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'FieldName':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Finally:
    """Original type: finally"""

    value: Tuple[Tok, Stmt]

    @classmethod
    def from_json(cls, x: Any) -> 'Finally':
        return cls((lambda x: (Tok.from_json(x[0]), Stmt.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Finally':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ForEach:
    """Original type: for_each"""

    value: Tuple[Pattern, Tok, Expr]

    @classmethod
    def from_json(cls, x: Any) -> 'ForEach':
        return cls((lambda x: (Pattern.from_json(x[0]), Tok.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x))

    def to_json(self) -> Any:
        return (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'ForEach':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ForClassic:
    """Original type: for_header = [ ... | ForClassic of ... | ... ]"""

    value: Tuple[List[ForVarOrExpr], Optional[Expr], Optional[Expr]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForClassic'

    def to_json(self) -> Any:
        return ['ForClassic', (lambda x: [_atd_write_list((lambda x: x.to_json()))(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), _atd_write_nullable((lambda x: x.to_json()))(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForEach_:
    """Original type: for_header = [ ... | ForEach of ... | ... ]"""

    value: ForEach

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForEach_'

    def to_json(self) -> Any:
        return ['ForEach', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class MultiForEach_:
    """Original type: for_header = [ ... | MultiForEach of ... | ... ]"""

    value: List[MultiForEach]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'MultiForEach_'

    def to_json(self) -> Any:
        return ['MultiForEach', _atd_write_list((lambda x: x.to_json()))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForIn:
    """Original type: for_header = [ ... | ForIn of ... | ... ]"""

    value: Tuple[List[ForVarOrExpr], List[Expr]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForIn'

    def to_json(self) -> Any:
        return ['ForIn', (lambda x: [_atd_write_list((lambda x: x.to_json()))(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForHeader:
    """Original type: for_header = [ ... ]"""

    value: Union[ForClassic, ForEach_, MultiForEach_, ForIn]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ForHeader':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ForClassic':
                return cls(ForClassic((lambda x: (_atd_read_list(ForVarOrExpr.from_json)(x[0]), _atd_read_nullable(Expr.from_json)(x[1]), _atd_read_nullable(Expr.from_json)(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'ForEach':
                return cls(ForEach_(ForEach.from_json(x[1])))
            if cons == 'MultiForEach':
                return cls(MultiForEach_(_atd_read_list(MultiForEach.from_json)(x[1])))
            if cons == 'ForIn':
                return cls(ForIn((lambda x: (_atd_read_list(ForVarOrExpr.from_json)(x[0]), _atd_read_list(Expr.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('ForHeader', x)
        _atd_bad_json('ForHeader', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ForHeader':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class CompFor:
    """Original type: for_or_if_comp = [ ... | CompFor of ... | ... ]"""

    value: Tuple[Tok, Pattern, Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CompFor'

    def to_json(self) -> Any:
        return ['CompFor', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2]), (lambda x: x.to_json())(x[3])] if isinstance(x, tuple) and len(x) == 4 else _atd_bad_python('tuple of length 4', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class CompIf:
    """Original type: for_or_if_comp = [ ... | CompIf of ... | ... ]"""

    value: Tuple[Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'CompIf'

    def to_json(self) -> Any:
        return ['CompIf', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForOrIfComp:
    """Original type: for_or_if_comp = [ ... ]"""

    value: Union[CompFor, CompIf]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ForOrIfComp':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'CompFor':
                return cls(CompFor((lambda x: (Tok.from_json(x[0]), Pattern.from_json(x[1]), Tok.from_json(x[2]), Expr.from_json(x[3])) if isinstance(x, list) and len(x) == 4 else _atd_bad_json('array of length 4', x))(x[1])))
            if cons == 'CompIf':
                return cls(CompIf((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('ForOrIfComp', x)
        _atd_bad_json('ForOrIfComp', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ForOrIfComp':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ForInitVar:
    """Original type: for_var_or_expr = [ ... | ForInitVar of ... | ... ]"""

    value: Tuple[Entity, VariableDefinition]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForInitVar'

    def to_json(self) -> Any:
        return ['ForInitVar', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForInitExpr:
    """Original type: for_var_or_expr = [ ... | ForInitExpr of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ForInitExpr'

    def to_json(self) -> Any:
        return ['ForInitExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ForVarOrExpr:
    """Original type: for_var_or_expr = [ ... ]"""

    value: Union[ForInitVar, ForInitExpr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ForVarOrExpr':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ForInitVar':
                return cls(ForInitVar((lambda x: (Entity.from_json(x[0]), VariableDefinition.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'ForInitExpr':
                return cls(ForInitExpr(Expr.from_json(x[1])))
            _atd_bad_json('ForVarOrExpr', x)
        _atd_bad_json('ForVarOrExpr', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ForVarOrExpr':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FBStmt:
    """Original type: function_body = [ ... | FBStmt of ... | ... ]"""

    value: Stmt

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FBStmt'

    def to_json(self) -> Any:
        return ['FBStmt', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FBExpr:
    """Original type: function_body = [ ... | FBExpr of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FBExpr'

    def to_json(self) -> Any:
        return ['FBExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FBDecl:
    """Original type: function_body = [ ... | FBDecl of ... | ... ]"""

    value: Sc

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FBDecl'

    def to_json(self) -> Any:
        return ['FBDecl', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FBNothing:
    """Original type: function_body = [ ... | FBNothing | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FBNothing'

    @staticmethod
    def to_json() -> Any:
        return 'FBNothing'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FunctionBody:
    """Original type: function_body = [ ... ]"""

    value: Union[FBStmt, FBExpr, FBDecl, FBNothing]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'FunctionBody':
        if isinstance(x, str):
            if x == 'FBNothing':
                return cls(FBNothing())
            _atd_bad_json('FunctionBody', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'FBStmt':
                return cls(FBStmt(Stmt.from_json(x[1])))
            if cons == 'FBExpr':
                return cls(FBExpr(Expr.from_json(x[1])))
            if cons == 'FBDecl':
                return cls(FBDecl(Sc.from_json(x[1])))
            _atd_bad_json('FunctionBody', x)
        _atd_bad_json('FunctionBody', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'FunctionBody':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FunctionDefinition:
    """Original type: function_definition = { ... }"""

    fkind: FunctionKindWrap
    fparams: Parameters
    frettype: Optional[Type]
    fbody: FunctionBody

    @classmethod
    def from_json(cls, x: Any) -> 'FunctionDefinition':
        if isinstance(x, dict):
            return cls(
                fkind=FunctionKindWrap.from_json(x['fkind']) if 'fkind' in x else _atd_missing_json_field('FunctionDefinition', 'fkind'),
                fparams=Parameters.from_json(x['fparams']) if 'fparams' in x else _atd_missing_json_field('FunctionDefinition', 'fparams'),
                frettype=_atd_read_nullable(Type.from_json)(x['frettype']) if 'frettype' in x else _atd_missing_json_field('FunctionDefinition', 'frettype'),
                fbody=FunctionBody.from_json(x['fbody']) if 'fbody' in x else _atd_missing_json_field('FunctionDefinition', 'fbody'),
            )
        else:
            _atd_bad_json('FunctionDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['fkind'] = (lambda x: x.to_json())(self.fkind)
        res['fparams'] = (lambda x: x.to_json())(self.fparams)
        res['frettype'] = _atd_write_nullable((lambda x: x.to_json()))(self.frettype)
        res['fbody'] = (lambda x: x.to_json())(self.fbody)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'FunctionDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class IdInfo:
    """Original type: id_info = { ... }"""

    id_resolved: Optional[ResolvedName] = None
    id_type: Optional[Type] = None
    id_svalue: Optional[Svalue] = None

    @classmethod
    def from_json(cls, x: Any) -> 'IdInfo':
        if isinstance(x, dict):
            return cls(
                id_resolved=ResolvedName.from_json(x['id_resolved']) if 'id_resolved' in x else None,
                id_type=Type.from_json(x['id_type']) if 'id_type' in x else None,
                id_svalue=Svalue.from_json(x['id_svalue']) if 'id_svalue' in x else None,
            )
        else:
            _atd_bad_json('IdInfo', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        if self.id_resolved is not None:
            res['id_resolved'] = (lambda x: x.to_json())(self.id_resolved)
        if self.id_type is not None:
            res['id_type'] = (lambda x: x.to_json())(self.id_type)
        if self.id_svalue is not None:
            res['id_svalue'] = (lambda x: x.to_json())(self.id_svalue)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'IdInfo':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Item:
    """Original type: item"""

    value: Stmt

    @classmethod
    def from_json(cls, x: Any) -> 'Item':
        return cls(Stmt.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Item':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class LNone:
    """Original type: label_ident = [ ... | LNone | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LNone'

    @staticmethod
    def to_json() -> Any:
        return 'LNone'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LId:
    """Original type: label_ident = [ ... | LId of ... | ... ]"""

    value: Label

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LId'

    def to_json(self) -> Any:
        return ['LId', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LInt:
    """Original type: label_ident = [ ... | LInt of ... | ... ]"""

    value: IntWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LInt'

    def to_json(self) -> Any:
        return ['LInt', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LDynamic:
    """Original type: label_ident = [ ... | LDynamic of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'LDynamic'

    def to_json(self) -> Any:
        return ['LDynamic', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class LabelIdent:
    """Original type: label_ident = [ ... ]"""

    value: Union[LNone, LId, LInt, LDynamic]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'LabelIdent':
        if isinstance(x, str):
            if x == 'LNone':
                return cls(LNone())
            _atd_bad_json('LabelIdent', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'LId':
                return cls(LId(Label.from_json(x[1])))
            if cons == 'LInt':
                return cls(LInt(IntWrap.from_json(x[1])))
            if cons == 'LDynamic':
                return cls(LDynamic(Expr.from_json(x[1])))
            _atd_bad_json('LabelIdent', x)
        _atd_bad_json('LabelIdent', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'LabelIdent':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class MacroDefinition:
    """Original type: macro_definition = { ... }"""

    macroparams: List[Ident]
    macrobody: List[Any_]

    @classmethod
    def from_json(cls, x: Any) -> 'MacroDefinition':
        if isinstance(x, dict):
            return cls(
                macroparams=_atd_read_list(Ident.from_json)(x['macroparams']) if 'macroparams' in x else _atd_missing_json_field('MacroDefinition', 'macroparams'),
                macrobody=_atd_read_list(Any_.from_json)(x['macrobody']) if 'macrobody' in x else _atd_missing_json_field('MacroDefinition', 'macrobody'),
            )
        else:
            _atd_bad_json('MacroDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['macroparams'] = _atd_write_list((lambda x: x.to_json()))(self.macroparams)
        res['macrobody'] = _atd_write_list((lambda x: x.to_json()))(self.macrobody)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'MacroDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ModuleDefinition:
    """Original type: module_definition = { ... }"""

    mbody: ModuleDefinitionKind

    @classmethod
    def from_json(cls, x: Any) -> 'ModuleDefinition':
        if isinstance(x, dict):
            return cls(
                mbody=ModuleDefinitionKind.from_json(x['mbody']) if 'mbody' in x else _atd_missing_json_field('ModuleDefinition', 'mbody'),
            )
        else:
            _atd_bad_json('ModuleDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['mbody'] = (lambda x: x.to_json())(self.mbody)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'ModuleDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ModuleAlias:
    """Original type: module_definition_kind = [ ... | ModuleAlias of ... | ... ]"""

    value: DottedIdent

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ModuleAlias'

    def to_json(self) -> Any:
        return ['ModuleAlias', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ModuleStruct:
    """Original type: module_definition_kind = [ ... | ModuleStruct of ... | ... ]"""

    value: Tuple[Optional[DottedIdent], List[Item]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ModuleStruct'

    def to_json(self) -> Any:
        return ['ModuleStruct', (lambda x: [_atd_write_nullable((lambda x: x.to_json()))(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherModule:
    """Original type: module_definition_kind = [ ... | OtherModule of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherModule'

    def to_json(self) -> Any:
        return ['OtherModule', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ModuleDefinitionKind:
    """Original type: module_definition_kind = [ ... ]"""

    value: Union[ModuleAlias, ModuleStruct, OtherModule]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'ModuleDefinitionKind':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ModuleAlias':
                return cls(ModuleAlias(DottedIdent.from_json(x[1])))
            if cons == 'ModuleStruct':
                return cls(ModuleStruct((lambda x: (_atd_read_nullable(DottedIdent.from_json)(x[0]), _atd_read_list(Item.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherModule':
                return cls(OtherModule((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('ModuleDefinitionKind', x)
        _atd_bad_json('ModuleDefinitionKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'ModuleDefinitionKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class FE:
    """Original type: multi_for_each = [ ... | FE of ... | ... ]"""

    value: ForEach

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FE'

    def to_json(self) -> Any:
        return ['FE', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class FECond:
    """Original type: multi_for_each = [ ... | FECond of ... | ... ]"""

    value: Tuple[ForEach, Tok, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'FECond'

    def to_json(self) -> Any:
        return ['FECond', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class MultiForEach:
    """Original type: multi_for_each = [ ... ]"""

    value: Union[FE, FECond]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'MultiForEach':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'FE':
                return cls(FE(ForEach.from_json(x[1])))
            if cons == 'FECond':
                return cls(FECond((lambda x: (ForEach.from_json(x[0]), Tok.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            _atd_bad_json('MultiForEach', x)
        _atd_bad_json('MultiForEach', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'MultiForEach':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Id:
    """Original type: name = [ ... | Id of ... | ... ]"""

    value: Tuple[Ident, IdInfo]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Id'

    def to_json(self) -> Any:
        return ['Id', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class IdQualified:
    """Original type: name = [ ... | IdQualified of ... | ... ]"""

    value: QualifiedInfo

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'IdQualified'

    def to_json(self) -> Any:
        return ['IdQualified', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Name:
    """Original type: name = [ ... ]"""

    value: Union[Id, IdQualified]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Name':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Id':
                return cls(Id((lambda x: (Ident.from_json(x[0]), IdInfo.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'IdQualified':
                return cls(IdQualified(QualifiedInfo.from_json(x[1])))
            _atd_bad_json('Name', x)
        _atd_bad_json('Name', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Name':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class OrConstructor:
    """Original type: or_type_element = [ ... | OrConstructor of ... | ... ]"""

    value: Tuple[Ident, List[Type]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OrConstructor'

    def to_json(self) -> Any:
        return ['OrConstructor', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OrEnum:
    """Original type: or_type_element = [ ... | OrEnum of ... | ... ]"""

    value: Tuple[Ident, Optional[Expr]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OrEnum'

    def to_json(self) -> Any:
        return ['OrEnum', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OrUnion:
    """Original type: or_type_element = [ ... | OrUnion of ... | ... ]"""

    value: Tuple[Ident, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OrUnion'

    def to_json(self) -> Any:
        return ['OrUnion', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherOr:
    """Original type: or_type_element = [ ... | OtherOr of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherOr'

    def to_json(self) -> Any:
        return ['OtherOr', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OrTypeElement:
    """Original type: or_type_element = [ ... ]"""

    value: Union[OrConstructor, OrEnum, OrUnion, OtherOr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'OrTypeElement':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'OrConstructor':
                return cls(OrConstructor((lambda x: (Ident.from_json(x[0]), _atd_read_list(Type.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OrEnum':
                return cls(OrEnum((lambda x: (Ident.from_json(x[0]), _atd_read_nullable(Expr.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OrUnion':
                return cls(OrUnion((lambda x: (Ident.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherOr':
                return cls(OtherOr((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('OrTypeElement', x)
        _atd_bad_json('OrTypeElement', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'OrTypeElement':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ParamClassic:
    """Original type: parameter = [ ... | ParamClassic of ... | ... ]"""

    value: ParameterClassic

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ParamClassic'

    def to_json(self) -> Any:
        return ['ParamClassic', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ParamPattern:
    """Original type: parameter = [ ... | ParamPattern of ... | ... ]"""

    value: Pattern

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ParamPattern'

    def to_json(self) -> Any:
        return ['ParamPattern', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ParamRest:
    """Original type: parameter = [ ... | ParamRest of ... | ... ]"""

    value: Tuple[Tok, ParameterClassic]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ParamRest'

    def to_json(self) -> Any:
        return ['ParamRest', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class ParamHashSplat:
    """Original type: parameter = [ ... | ParamHashSplat of ... | ... ]"""

    value: Tuple[Tok, ParameterClassic]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ParamHashSplat'

    def to_json(self) -> Any:
        return ['ParamHashSplat', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherParam:
    """Original type: parameter = [ ... | OtherParam of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherParam'

    def to_json(self) -> Any:
        return ['OtherParam', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Parameter:
    """Original type: parameter = [ ... ]"""

    value: Union[ParamClassic, ParamPattern, ParamRest, ParamHashSplat, OtherParam]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Parameter':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ParamClassic':
                return cls(ParamClassic(ParameterClassic.from_json(x[1])))
            if cons == 'ParamPattern':
                return cls(ParamPattern(Pattern.from_json(x[1])))
            if cons == 'ParamRest':
                return cls(ParamRest((lambda x: (Tok.from_json(x[0]), ParameterClassic.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'ParamHashSplat':
                return cls(ParamHashSplat((lambda x: (Tok.from_json(x[0]), ParameterClassic.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherParam':
                return cls(OtherParam((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Parameter', x)
        _atd_bad_json('Parameter', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Parameter':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ParameterClassic:
    """Original type: parameter_classic = { ... }"""

    pname: Optional[Ident]
    ptype: Optional[Type]
    pdefault: Optional[Expr]
    pattrs: List[Attribute]
    pinfo: IdInfo

    @classmethod
    def from_json(cls, x: Any) -> 'ParameterClassic':
        if isinstance(x, dict):
            return cls(
                pname=_atd_read_nullable(Ident.from_json)(x['pname']) if 'pname' in x else _atd_missing_json_field('ParameterClassic', 'pname'),
                ptype=_atd_read_nullable(Type.from_json)(x['ptype']) if 'ptype' in x else _atd_missing_json_field('ParameterClassic', 'ptype'),
                pdefault=_atd_read_nullable(Expr.from_json)(x['pdefault']) if 'pdefault' in x else _atd_missing_json_field('ParameterClassic', 'pdefault'),
                pattrs=_atd_read_list(Attribute.from_json)(x['pattrs']) if 'pattrs' in x else _atd_missing_json_field('ParameterClassic', 'pattrs'),
                pinfo=IdInfo.from_json(x['pinfo']) if 'pinfo' in x else _atd_missing_json_field('ParameterClassic', 'pinfo'),
            )
        else:
            _atd_bad_json('ParameterClassic', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['pname'] = _atd_write_nullable((lambda x: x.to_json()))(self.pname)
        res['ptype'] = _atd_write_nullable((lambda x: x.to_json()))(self.ptype)
        res['pdefault'] = _atd_write_nullable((lambda x: x.to_json()))(self.pdefault)
        res['pattrs'] = _atd_write_list((lambda x: x.to_json()))(self.pattrs)
        res['pinfo'] = (lambda x: x.to_json())(self.pinfo)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'ParameterClassic':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Parameters:
    """Original type: parameters"""

    value: List[Parameter]

    @classmethod
    def from_json(cls, x: Any) -> 'Parameters':
        return cls(_atd_read_list(Parameter.from_json)(x))

    def to_json(self) -> Any:
        return _atd_write_list((lambda x: x.to_json()))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Parameters':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class PatLiteral:
    """Original type: pattern = [ ... | PatLiteral of ... | ... ]"""

    value: Literal

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatLiteral'

    def to_json(self) -> Any:
        return ['PatLiteral', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatConstructor:
    """Original type: pattern = [ ... | PatConstructor of ... | ... ]"""

    value: Tuple[Name, List[Pattern]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatConstructor'

    def to_json(self) -> Any:
        return ['PatConstructor', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatRecord:
    """Original type: pattern = [ ... | PatRecord of ... | ... ]"""

    value: DottedIdentPatternListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatRecord'

    def to_json(self) -> Any:
        return ['PatRecord', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatId:
    """Original type: pattern = [ ... | PatId of ... | ... ]"""

    value: Tuple[Ident, IdInfo]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatId'

    def to_json(self) -> Any:
        return ['PatId', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatTuple:
    """Original type: pattern = [ ... | PatTuple of ... | ... ]"""

    value: PatternListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatTuple'

    def to_json(self) -> Any:
        return ['PatTuple', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatList:
    """Original type: pattern = [ ... | PatList of ... | ... ]"""

    value: PatternListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatList'

    def to_json(self) -> Any:
        return ['PatList', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatKeyVal:
    """Original type: pattern = [ ... | PatKeyVal of ... | ... ]"""

    value: Tuple[Pattern, Pattern]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatKeyVal'

    def to_json(self) -> Any:
        return ['PatKeyVal', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatUnderscore:
    """Original type: pattern = [ ... | PatUnderscore of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatUnderscore'

    def to_json(self) -> Any:
        return ['PatUnderscore', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatDisj:
    """Original type: pattern = [ ... | PatDisj of ... | ... ]"""

    value: Tuple[Pattern, Pattern]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatDisj'

    def to_json(self) -> Any:
        return ['PatDisj', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatTyped:
    """Original type: pattern = [ ... | PatTyped of ... | ... ]"""

    value: Tuple[Pattern, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatTyped'

    def to_json(self) -> Any:
        return ['PatTyped', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatWhen:
    """Original type: pattern = [ ... | PatWhen of ... | ... ]"""

    value: Tuple[Pattern, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatWhen'

    def to_json(self) -> Any:
        return ['PatWhen', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatAs:
    """Original type: pattern = [ ... | PatAs of ... | ... ]"""

    value: Tuple[Pattern, Tuple[Ident, IdInfo]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatAs'

    def to_json(self) -> Any:
        return ['PatAs', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class PatType:
    """Original type: pattern = [ ... | PatType of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'PatType'

    def to_json(self) -> Any:
        return ['PatType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherPat:
    """Original type: pattern = [ ... | OtherPat of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherPat'

    def to_json(self) -> Any:
        return ['OtherPat', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Pattern:
    """Original type: pattern = [ ... ]"""

    value: Union[PatLiteral, PatConstructor, PatRecord, PatId, PatTuple, PatList, PatKeyVal, PatUnderscore, PatDisj, PatTyped, PatWhen, PatAs, PatType, OtherPat]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Pattern':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'PatLiteral':
                return cls(PatLiteral(Literal.from_json(x[1])))
            if cons == 'PatConstructor':
                return cls(PatConstructor((lambda x: (Name.from_json(x[0]), _atd_read_list(Pattern.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatRecord':
                return cls(PatRecord(DottedIdentPatternListBracket.from_json(x[1])))
            if cons == 'PatId':
                return cls(PatId((lambda x: (Ident.from_json(x[0]), IdInfo.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatTuple':
                return cls(PatTuple(PatternListBracket.from_json(x[1])))
            if cons == 'PatList':
                return cls(PatList(PatternListBracket.from_json(x[1])))
            if cons == 'PatKeyVal':
                return cls(PatKeyVal((lambda x: (Pattern.from_json(x[0]), Pattern.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatUnderscore':
                return cls(PatUnderscore(Tok.from_json(x[1])))
            if cons == 'PatDisj':
                return cls(PatDisj((lambda x: (Pattern.from_json(x[0]), Pattern.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatTyped':
                return cls(PatTyped((lambda x: (Pattern.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatWhen':
                return cls(PatWhen((lambda x: (Pattern.from_json(x[0]), Expr.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatAs':
                return cls(PatAs((lambda x: (Pattern.from_json(x[0]), (lambda x: (Ident.from_json(x[0]), IdInfo.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'PatType':
                return cls(PatType(Type.from_json(x[1])))
            if cons == 'OtherPat':
                return cls(OtherPat((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Pattern', x)
        _atd_bad_json('Pattern', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Pattern':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class QualifiedInfo:
    """Original type: qualified_info = { ... }"""

    name_last: Tuple[Ident, Optional[TypeArguments]]
    name_info: IdInfo
    name_middle: Optional[Qualifier] = None
    name_top: Optional[Tok] = None

    @classmethod
    def from_json(cls, x: Any) -> 'QualifiedInfo':
        if isinstance(x, dict):
            return cls(
                name_last=(lambda x: (Ident.from_json(x[0]), _atd_read_nullable(TypeArguments.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x['name_last']) if 'name_last' in x else _atd_missing_json_field('QualifiedInfo', 'name_last'),
                name_info=IdInfo.from_json(x['name_info']) if 'name_info' in x else _atd_missing_json_field('QualifiedInfo', 'name_info'),
                name_middle=Qualifier.from_json(x['name_middle']) if 'name_middle' in x else None,
                name_top=Tok.from_json(x['name_top']) if 'name_top' in x else None,
            )
        else:
            _atd_bad_json('QualifiedInfo', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['name_last'] = (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.name_last)
        res['name_info'] = (lambda x: x.to_json())(self.name_info)
        if self.name_middle is not None:
            res['name_middle'] = (lambda x: x.to_json())(self.name_middle)
        if self.name_top is not None:
            res['name_top'] = (lambda x: x.to_json())(self.name_top)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'QualifiedInfo':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class QDots:
    """Original type: qualifier = [ ... | QDots of ... | ... ]"""

    value: List[Tuple[Ident, Optional[TypeArguments]]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'QDots'

    def to_json(self) -> Any:
        return ['QDots', _atd_write_list((lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x)))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class QExpr:
    """Original type: qualifier = [ ... | QExpr of ... | ... ]"""

    value: Tuple[Expr, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'QExpr'

    def to_json(self) -> Any:
        return ['QExpr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Qualifier:
    """Original type: qualifier = [ ... ]"""

    value: Union[QDots, QExpr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Qualifier':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'QDots':
                return cls(QDots(_atd_read_list((lambda x: (Ident.from_json(x[0]), _atd_read_nullable(TypeArguments.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x)))(x[1])))
            if cons == 'QExpr':
                return cls(QExpr((lambda x: (Expr.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Qualifier', x)
        _atd_bad_json('Qualifier', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Qualifier':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class ExprStmt:
    """Original type: stmt = [ ... | ExprStmt of ... | ... ]"""

    value: Tuple[Expr, Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'ExprStmt'

    def to_json(self) -> Any:
        return ['ExprStmt', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Block:
    """Original type: stmt = [ ... | Block of ... | ... ]"""

    value: StmtListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Block'

    def to_json(self) -> Any:
        return ['Block', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class If:
    """Original type: stmt = [ ... | If of ... | ... ]"""

    value: Tuple[Tok, Condition, Stmt, Optional[Stmt]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'If'

    def to_json(self) -> Any:
        return ['If', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2]), _atd_write_nullable((lambda x: x.to_json()))(x[3])] if isinstance(x, tuple) and len(x) == 4 else _atd_bad_python('tuple of length 4', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class While:
    """Original type: stmt = [ ... | While of ... | ... ]"""

    value: Tuple[Tok, Condition, Stmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'While'

    def to_json(self) -> Any:
        return ['While', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Return:
    """Original type: stmt = [ ... | Return of ... | ... ]"""

    value: Tuple[Tok, Optional[Expr], Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Return'

    def to_json(self) -> Any:
        return ['Return', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DoWhile:
    """Original type: stmt = [ ... | DoWhile of ... | ... ]"""

    value: Tuple[Tok, Stmt, Expr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DoWhile'

    def to_json(self) -> Any:
        return ['DoWhile', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class For:
    """Original type: stmt = [ ... | For of ... | ... ]"""

    value: Tuple[Tok, ForHeader, Stmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'For'

    def to_json(self) -> Any:
        return ['For', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Switch:
    """Original type: stmt = [ ... | Switch of ... | ... ]"""

    value: Tuple[Tok, Optional[Condition], List[CaseAndBody]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Switch'

    def to_json(self) -> Any:
        return ['Switch', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: x.to_json()))(x[1]), _atd_write_list((lambda x: x.to_json()))(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Continue:
    """Original type: stmt = [ ... | Continue of ... | ... ]"""

    value: Tuple[Tok, LabelIdent, Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Continue'

    def to_json(self) -> Any:
        return ['Continue', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Break:
    """Original type: stmt = [ ... | Break of ... | ... ]"""

    value: Tuple[Tok, LabelIdent, Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Break'

    def to_json(self) -> Any:
        return ['Break', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Label_:
    """Original type: stmt = [ ... | Label of ... | ... ]"""

    value: Tuple[Label, Stmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Label_'

    def to_json(self) -> Any:
        return ['Label', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Goto:
    """Original type: stmt = [ ... | Goto of ... | ... ]"""

    value: Tuple[Tok, Label]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Goto'

    def to_json(self) -> Any:
        return ['Goto', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Throw:
    """Original type: stmt = [ ... | Throw of ... | ... ]"""

    value: Tuple[Tok, Expr, Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Throw'

    def to_json(self) -> Any:
        return ['Throw', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Try:
    """Original type: stmt = [ ... | Try of ... | ... ]"""

    value: Tuple[Tok, Stmt, List[Catch], Optional[Finally]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Try'

    def to_json(self) -> Any:
        return ['Try', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), _atd_write_list((lambda x: x.to_json()))(x[2]), _atd_write_nullable((lambda x: x.to_json()))(x[3])] if isinstance(x, tuple) and len(x) == 4 else _atd_bad_python('tuple of length 4', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class WithUsingResource:
    """Original type: stmt = [ ... | WithUsingResource of ... | ... ]"""

    value: Tuple[Tok, List[Stmt], Stmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'WithUsingResource'

    def to_json(self) -> Any:
        return ['WithUsingResource', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Assert:
    """Original type: stmt = [ ... | Assert of ... | ... ]"""

    value: Tuple[Tok, Arguments, Sc]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Assert'

    def to_json(self) -> Any:
        return ['Assert', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DefStmt:
    """Original type: stmt = [ ... | DefStmt of ... | ... ]"""

    value: Definition

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DefStmt'

    def to_json(self) -> Any:
        return ['DefStmt', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class DirectiveStmt:
    """Original type: stmt = [ ... | DirectiveStmt of ... | ... ]"""

    value: Directive

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'DirectiveStmt'

    def to_json(self) -> Any:
        return ['DirectiveStmt', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherStmt:
    """Original type: stmt = [ ... | OtherStmt of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherStmt'

    def to_json(self) -> Any:
        return ['OtherStmt', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Stmt:
    """Original type: stmt = [ ... ]"""

    value: Union[ExprStmt, Block, If, While, Return, DoWhile, For, Switch, Continue, Break, Label_, Goto, Throw, Try, WithUsingResource, Assert, DefStmt, DirectiveStmt, OtherStmt]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Stmt':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'ExprStmt':
                return cls(ExprStmt((lambda x: (Expr.from_json(x[0]), Sc.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Block':
                return cls(Block(StmtListBracket.from_json(x[1])))
            if cons == 'If':
                return cls(If((lambda x: (Tok.from_json(x[0]), Condition.from_json(x[1]), Stmt.from_json(x[2]), _atd_read_nullable(Stmt.from_json)(x[3])) if isinstance(x, list) and len(x) == 4 else _atd_bad_json('array of length 4', x))(x[1])))
            if cons == 'While':
                return cls(While((lambda x: (Tok.from_json(x[0]), Condition.from_json(x[1]), Stmt.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Return':
                return cls(Return((lambda x: (Tok.from_json(x[0]), _atd_read_nullable(Expr.from_json)(x[1]), Sc.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'DoWhile':
                return cls(DoWhile((lambda x: (Tok.from_json(x[0]), Stmt.from_json(x[1]), Expr.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'For':
                return cls(For((lambda x: (Tok.from_json(x[0]), ForHeader.from_json(x[1]), Stmt.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Switch':
                return cls(Switch((lambda x: (Tok.from_json(x[0]), _atd_read_nullable(Condition.from_json)(x[1]), _atd_read_list(CaseAndBody.from_json)(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Continue':
                return cls(Continue((lambda x: (Tok.from_json(x[0]), LabelIdent.from_json(x[1]), Sc.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Break':
                return cls(Break((lambda x: (Tok.from_json(x[0]), LabelIdent.from_json(x[1]), Sc.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Label':
                return cls(Label_((lambda x: (Label.from_json(x[0]), Stmt.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Goto':
                return cls(Goto((lambda x: (Tok.from_json(x[0]), Label.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'Throw':
                return cls(Throw((lambda x: (Tok.from_json(x[0]), Expr.from_json(x[1]), Sc.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Try':
                return cls(Try((lambda x: (Tok.from_json(x[0]), Stmt.from_json(x[1]), _atd_read_list(Catch.from_json)(x[2]), _atd_read_nullable(Finally.from_json)(x[3])) if isinstance(x, list) and len(x) == 4 else _atd_bad_json('array of length 4', x))(x[1])))
            if cons == 'WithUsingResource':
                return cls(WithUsingResource((lambda x: (Tok.from_json(x[0]), _atd_read_list(Stmt.from_json)(x[1]), Stmt.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'Assert':
                return cls(Assert((lambda x: (Tok.from_json(x[0]), Arguments.from_json(x[1]), Sc.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'DefStmt':
                return cls(DefStmt(Definition.from_json(x[1])))
            if cons == 'DirectiveStmt':
                return cls(DirectiveStmt(Directive.from_json(x[1])))
            if cons == 'OtherStmt':
                return cls(OtherStmt((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Stmt', x)
        _atd_bad_json('Stmt', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Stmt':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Lit:
    """Original type: svalue = [ ... | Lit of ... | ... ]"""

    value: Literal

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Lit'

    def to_json(self) -> Any:
        return ['Lit', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Cst:
    """Original type: svalue = [ ... | Cst of ... | ... ]"""

    value: ConstType

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Cst'

    def to_json(self) -> Any:
        return ['Cst', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Sym:
    """Original type: svalue = [ ... | Sym of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Sym'

    def to_json(self) -> Any:
        return ['Sym', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NotCst:
    """Original type: svalue = [ ... | NotCst | ... ]"""

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NotCst'

    @staticmethod
    def to_json() -> Any:
        return 'NotCst'

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Svalue:
    """Original type: svalue = [ ... ]"""

    value: Union[Lit, Cst, Sym, NotCst]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Svalue':
        if isinstance(x, str):
            if x == 'NotCst':
                return cls(NotCst())
            _atd_bad_json('Svalue', x)
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'Lit':
                return cls(Lit(Literal.from_json(x[1])))
            if cons == 'Cst':
                return cls(Cst(ConstType.from_json(x[1])))
            if cons == 'Sym':
                return cls(Sym(Expr.from_json(x[1])))
            _atd_bad_json('Svalue', x)
        _atd_bad_json('Svalue', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Svalue':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TyN:
    """Original type: type_ = [ ... | TyN of ... | ... ]"""

    value: Name

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyN'

    def to_json(self) -> Any:
        return ['TyN', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyApply:
    """Original type: type_ = [ ... | TyApply of ... | ... ]"""

    value: Tuple[Type, TypeArguments]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyApply'

    def to_json(self) -> Any:
        return ['TyApply', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyFun:
    """Original type: type_ = [ ... | TyFun of ... | ... ]"""

    value: Tuple[List[Parameter], Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyFun'

    def to_json(self) -> Any:
        return ['TyFun', (lambda x: [_atd_write_list((lambda x: x.to_json()))(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyArray:
    """Original type: type_ = [ ... | TyArray of ... | ... ]"""

    value: Tuple[ExprNullableBracket, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyArray'

    def to_json(self) -> Any:
        return ['TyArray', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyTuple:
    """Original type: type_ = [ ... | TyTuple of ... | ... ]"""

    value: TypeListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyTuple'

    def to_json(self) -> Any:
        return ['TyTuple', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyVar:
    """Original type: type_ = [ ... | TyVar of ... | ... ]"""

    value: Ident

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyVar'

    def to_json(self) -> Any:
        return ['TyVar', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyAny:
    """Original type: type_ = [ ... | TyAny of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyAny'

    def to_json(self) -> Any:
        return ['TyAny', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyPointer:
    """Original type: type_ = [ ... | TyPointer of ... | ... ]"""

    value: Tuple[Tok, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyPointer'

    def to_json(self) -> Any:
        return ['TyPointer', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyRef:
    """Original type: type_ = [ ... | TyRef of ... | ... ]"""

    value: Tuple[Tok, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyRef'

    def to_json(self) -> Any:
        return ['TyRef', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyQuestion:
    """Original type: type_ = [ ... | TyQuestion of ... | ... ]"""

    value: Tuple[Type, Tok]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyQuestion'

    def to_json(self) -> Any:
        return ['TyQuestion', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyRest:
    """Original type: type_ = [ ... | TyRest of ... | ... ]"""

    value: Tuple[Tok, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyRest'

    def to_json(self) -> Any:
        return ['TyRest', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyAnd:
    """Original type: type_ = [ ... | TyAnd of ... | ... ]"""

    value: Tuple[Type, Tok, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyAnd'

    def to_json(self) -> Any:
        return ['TyAnd', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyOr:
    """Original type: type_ = [ ... | TyOr of ... | ... ]"""

    value: Tuple[Type, Tok, Type]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyOr'

    def to_json(self) -> Any:
        return ['TyOr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyRecordAnon:
    """Original type: type_ = [ ... | TyRecordAnon of ... | ... ]"""

    value: Tuple[ClassKindWrap, FieldListBracket]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyRecordAnon'

    def to_json(self) -> Any:
        return ['TyRecordAnon', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TyExpr:
    """Original type: type_ = [ ... | TyExpr of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TyExpr'

    def to_json(self) -> Any:
        return ['TyExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherType:
    """Original type: type_ = [ ... | OtherType of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherType'

    def to_json(self) -> Any:
        return ['OtherType', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Type:
    """Original type: type_ = [ ... ]"""

    value: Union[TyN, TyApply, TyFun, TyArray, TyTuple, TyVar, TyAny, TyPointer, TyRef, TyQuestion, TyRest, TyAnd, TyOr, TyRecordAnon, TyExpr, OtherType]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'Type':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'TyN':
                return cls(TyN(Name.from_json(x[1])))
            if cons == 'TyApply':
                return cls(TyApply((lambda x: (Type.from_json(x[0]), TypeArguments.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyFun':
                return cls(TyFun((lambda x: (_atd_read_list(Parameter.from_json)(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyArray':
                return cls(TyArray((lambda x: (ExprNullableBracket.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyTuple':
                return cls(TyTuple(TypeListBracket.from_json(x[1])))
            if cons == 'TyVar':
                return cls(TyVar(Ident.from_json(x[1])))
            if cons == 'TyAny':
                return cls(TyAny(Tok.from_json(x[1])))
            if cons == 'TyPointer':
                return cls(TyPointer((lambda x: (Tok.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyRef':
                return cls(TyRef((lambda x: (Tok.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyQuestion':
                return cls(TyQuestion((lambda x: (Type.from_json(x[0]), Tok.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyRest':
                return cls(TyRest((lambda x: (Tok.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyAnd':
                return cls(TyAnd((lambda x: (Type.from_json(x[0]), Tok.from_json(x[1]), Type.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'TyOr':
                return cls(TyOr((lambda x: (Type.from_json(x[0]), Tok.from_json(x[1]), Type.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'TyRecordAnon':
                return cls(TyRecordAnon((lambda x: (ClassKindWrap.from_json(x[0]), FieldListBracket.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TyExpr':
                return cls(TyExpr(Expr.from_json(x[1])))
            if cons == 'OtherType':
                return cls(OtherType((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('Type', x)
        _atd_bad_json('Type', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'Type':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TA:
    """Original type: type_argument = [ ... | TA of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TA'

    def to_json(self) -> Any:
        return ['TA', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TAWildcard:
    """Original type: type_argument = [ ... | TAWildcard of ... | ... ]"""

    value: Tuple[Tok, Optional[Tuple[BoolWrap, Type]]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TAWildcard'

    def to_json(self) -> Any:
        return ['TAWildcard', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_nullable((lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x)))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TAExpr:
    """Original type: type_argument = [ ... | TAExpr of ... | ... ]"""

    value: Expr

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TAExpr'

    def to_json(self) -> Any:
        return ['TAExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherTypeArg:
    """Original type: type_argument = [ ... | OtherTypeArg of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherTypeArg'

    def to_json(self) -> Any:
        return ['OtherTypeArg', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TypeArgument:
    """Original type: type_argument = [ ... ]"""

    value: Union[TA, TAWildcard, TAExpr, OtherTypeArg]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'TypeArgument':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'TA':
                return cls(TA(Type.from_json(x[1])))
            if cons == 'TAWildcard':
                return cls(TAWildcard((lambda x: (Tok.from_json(x[0]), _atd_read_nullable((lambda x: (BoolWrap.from_json(x[0]), Type.from_json(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x)))(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'TAExpr':
                return cls(TAExpr(Expr.from_json(x[1])))
            if cons == 'OtherTypeArg':
                return cls(OtherTypeArg((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('TypeArgument', x)
        _atd_bad_json('TypeArgument', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeArgument':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeArguments:
    """Original type: type_arguments"""

    value: TypeArgumentListBracket

    @classmethod
    def from_json(cls, x: Any) -> 'TypeArguments':
        return cls(TypeArgumentListBracket.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeArguments':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeDefinition:
    """Original type: type_definition = { ... }"""

    tbody: TypeDefinitionKind

    @classmethod
    def from_json(cls, x: Any) -> 'TypeDefinition':
        if isinstance(x, dict):
            return cls(
                tbody=TypeDefinitionKind.from_json(x['tbody']) if 'tbody' in x else _atd_missing_json_field('TypeDefinition', 'tbody'),
            )
        else:
            _atd_bad_json('TypeDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['tbody'] = (lambda x: x.to_json())(self.tbody)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class OrType:
    """Original type: type_definition_kind = [ ... | OrType of ... | ... ]"""

    value: List[OrTypeElement]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OrType'

    def to_json(self) -> Any:
        return ['OrType', _atd_write_list((lambda x: x.to_json()))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AndType:
    """Original type: type_definition_kind = [ ... | AndType of ... | ... ]"""

    value: FieldListBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AndType'

    def to_json(self) -> Any:
        return ['AndType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AliasType:
    """Original type: type_definition_kind = [ ... | AliasType of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AliasType'

    def to_json(self) -> Any:
        return ['AliasType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class NewType:
    """Original type: type_definition_kind = [ ... | NewType of ... | ... ]"""

    value: Type

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'NewType'

    def to_json(self) -> Any:
        return ['NewType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class AbstractType:
    """Original type: type_definition_kind = [ ... | AbstractType of ... | ... ]"""

    value: Tok

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'AbstractType'

    def to_json(self) -> Any:
        return ['AbstractType', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Exception:
    """Original type: type_definition_kind = [ ... | Exception of ... | ... ]"""

    value: Tuple[Ident, List[Type]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'Exception'

    def to_json(self) -> Any:
        return ['Exception', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherTypeKind:
    """Original type: type_definition_kind = [ ... | OtherTypeKind of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherTypeKind'

    def to_json(self) -> Any:
        return ['OtherTypeKind', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TypeDefinitionKind:
    """Original type: type_definition_kind = [ ... ]"""

    value: Union[OrType, AndType, AliasType, NewType, AbstractType, Exception, OtherTypeKind]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'TypeDefinitionKind':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'OrType':
                return cls(OrType(_atd_read_list(OrTypeElement.from_json)(x[1])))
            if cons == 'AndType':
                return cls(AndType(FieldListBracket.from_json(x[1])))
            if cons == 'AliasType':
                return cls(AliasType(Type.from_json(x[1])))
            if cons == 'NewType':
                return cls(NewType(Type.from_json(x[1])))
            if cons == 'AbstractType':
                return cls(AbstractType(Tok.from_json(x[1])))
            if cons == 'Exception':
                return cls(Exception((lambda x: (Ident.from_json(x[0]), _atd_read_list(Type.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            if cons == 'OtherTypeKind':
                return cls(OtherTypeKind((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('TypeDefinitionKind', x)
        _atd_bad_json('TypeDefinitionKind', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeDefinitionKind':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TP:
    """Original type: type_parameter = [ ... | TP of ... | ... ]"""

    value: TypeParameterClassic

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'TP'

    def to_json(self) -> Any:
        return ['TP', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class OtherTypeParam:
    """Original type: type_parameter = [ ... | OtherTypeParam of ... | ... ]"""

    value: Tuple[TodoKind, List[Any_]]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'OtherTypeParam'

    def to_json(self) -> Any:
        return ['OtherTypeParam', (lambda x: [(lambda x: x.to_json())(x[0]), _atd_write_list((lambda x: x.to_json()))(x[1])] if isinstance(x, tuple) and len(x) == 2 else _atd_bad_python('tuple of length 2', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class TypeParameter:
    """Original type: type_parameter = [ ... ]"""

    value: Union[TP, OtherTypeParam]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'TypeParameter':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'TP':
                return cls(TP(TypeParameterClassic.from_json(x[1])))
            if cons == 'OtherTypeParam':
                return cls(OtherTypeParam((lambda x: (TodoKind.from_json(x[0]), _atd_read_list(Any_.from_json)(x[1])) if isinstance(x, list) and len(x) == 2 else _atd_bad_json('array of length 2', x))(x[1])))
            _atd_bad_json('TypeParameter', x)
        _atd_bad_json('TypeParameter', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeParameter':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeParameterClassic:
    """Original type: type_parameter_classic = { ... }"""

    tp_id: Ident
    tp_attrs: List[Attribute]
    tp_bounds: List[Type]
    tp_default: Optional[Type]
    tp_variance: Optional[VarianceWrap]

    @classmethod
    def from_json(cls, x: Any) -> 'TypeParameterClassic':
        if isinstance(x, dict):
            return cls(
                tp_id=Ident.from_json(x['tp_id']) if 'tp_id' in x else _atd_missing_json_field('TypeParameterClassic', 'tp_id'),
                tp_attrs=_atd_read_list(Attribute.from_json)(x['tp_attrs']) if 'tp_attrs' in x else _atd_missing_json_field('TypeParameterClassic', 'tp_attrs'),
                tp_bounds=_atd_read_list(Type.from_json)(x['tp_bounds']) if 'tp_bounds' in x else _atd_missing_json_field('TypeParameterClassic', 'tp_bounds'),
                tp_default=_atd_read_nullable(Type.from_json)(x['tp_default']) if 'tp_default' in x else _atd_missing_json_field('TypeParameterClassic', 'tp_default'),
                tp_variance=_atd_read_nullable(VarianceWrap.from_json)(x['tp_variance']) if 'tp_variance' in x else _atd_missing_json_field('TypeParameterClassic', 'tp_variance'),
            )
        else:
            _atd_bad_json('TypeParameterClassic', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['tp_id'] = (lambda x: x.to_json())(self.tp_id)
        res['tp_attrs'] = _atd_write_list((lambda x: x.to_json()))(self.tp_attrs)
        res['tp_bounds'] = _atd_write_list((lambda x: x.to_json()))(self.tp_bounds)
        res['tp_default'] = _atd_write_nullable((lambda x: x.to_json()))(self.tp_default)
        res['tp_variance'] = _atd_write_nullable((lambda x: x.to_json()))(self.tp_variance)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeParameterClassic':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class TypeParameters:
    """Original type: type_parameters"""

    value: List[TypeParameter]

    @classmethod
    def from_json(cls, x: Any) -> 'TypeParameters':
        return cls(_atd_read_list(TypeParameter.from_json)(x))

    def to_json(self) -> Any:
        return _atd_write_list((lambda x: x.to_json()))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'TypeParameters':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class VariableDefinition:
    """Original type: variable_definition = { ... }"""

    vinit: Optional[Expr] = None
    vtype: Optional[Type] = None

    @classmethod
    def from_json(cls, x: Any) -> 'VariableDefinition':
        if isinstance(x, dict):
            return cls(
                vinit=Expr.from_json(x['vinit']) if 'vinit' in x else None,
                vtype=Type.from_json(x['vtype']) if 'vtype' in x else None,
            )
        else:
            _atd_bad_json('VariableDefinition', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        if self.vinit is not None:
            res['vinit'] = (lambda x: x.to_json())(self.vinit)
        if self.vtype is not None:
            res['vtype'] = (lambda x: x.to_json())(self.vtype)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'VariableDefinition':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class Xml:
    """Original type: xml = { ... }"""

    xml_kind: XmlKind
    xml_attrs: List[XmlAttribute]
    xml_body: List[XmlBody]

    @classmethod
    def from_json(cls, x: Any) -> 'Xml':
        if isinstance(x, dict):
            return cls(
                xml_kind=XmlKind.from_json(x['xml_kind']) if 'xml_kind' in x else _atd_missing_json_field('Xml', 'xml_kind'),
                xml_attrs=_atd_read_list(XmlAttribute.from_json)(x['xml_attrs']) if 'xml_attrs' in x else _atd_missing_json_field('Xml', 'xml_attrs'),
                xml_body=_atd_read_list(XmlBody.from_json)(x['xml_body']) if 'xml_body' in x else _atd_missing_json_field('Xml', 'xml_body'),
            )
        else:
            _atd_bad_json('Xml', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['xml_kind'] = (lambda x: x.to_json())(self.xml_kind)
        res['xml_attrs'] = _atd_write_list((lambda x: x.to_json()))(self.xml_attrs)
        res['xml_body'] = _atd_write_list((lambda x: x.to_json()))(self.xml_body)
        return res

    @classmethod
    def from_json_string(cls, x: str) -> 'Xml':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class XmlAttrValue:
    """Original type: xml_attr_value"""

    value: Expr

    @classmethod
    def from_json(cls, x: Any) -> 'XmlAttrValue':
        return cls(Expr.from_json(x))

    def to_json(self) -> Any:
        return (lambda x: x.to_json())(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'XmlAttrValue':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class XmlAttr:
    """Original type: xml_attribute = [ ... | XmlAttr of ... | ... ]"""

    value: Tuple[Ident, Tok, XmlAttrValue]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlAttr'

    def to_json(self) -> Any:
        return ['XmlAttr', (lambda x: [(lambda x: x.to_json())(x[0]), (lambda x: x.to_json())(x[1]), (lambda x: x.to_json())(x[2])] if isinstance(x, tuple) and len(x) == 3 else _atd_bad_python('tuple of length 3', x))(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlAttrExpr:
    """Original type: xml_attribute = [ ... | XmlAttrExpr of ... | ... ]"""

    value: ExprBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlAttrExpr'

    def to_json(self) -> Any:
        return ['XmlAttrExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlAttribute:
    """Original type: xml_attribute = [ ... ]"""

    value: Union[XmlAttr, XmlAttrExpr]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'XmlAttribute':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'XmlAttr':
                return cls(XmlAttr((lambda x: (Ident.from_json(x[0]), Tok.from_json(x[1]), XmlAttrValue.from_json(x[2])) if isinstance(x, list) and len(x) == 3 else _atd_bad_json('array of length 3', x))(x[1])))
            if cons == 'XmlAttrExpr':
                return cls(XmlAttrExpr(ExprBracket.from_json(x[1])))
            _atd_bad_json('XmlAttribute', x)
        _atd_bad_json('XmlAttribute', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'XmlAttribute':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)

@dataclass
class XmlText:
    """Original type: xml_body = [ ... | XmlText of ... | ... ]"""

    value: StringWrap

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlText'

    def to_json(self) -> Any:
        return ['XmlText', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlExpr:
    """Original type: xml_body = [ ... | XmlExpr of ... | ... ]"""

    value: ExprNullableBracket

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlExpr'

    def to_json(self) -> Any:
        return ['XmlExpr', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlXml:
    """Original type: xml_body = [ ... | XmlXml of ... | ... ]"""

    value: Xml

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return 'XmlXml'

    def to_json(self) -> Any:
        return ['XmlXml', (lambda x: x.to_json())(self.value)]

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class XmlBody:
    """Original type: xml_body = [ ... ]"""

    value: Union[XmlText, XmlExpr, XmlXml]

    @property
    def kind(self) -> str:
        """Name of the class representing this variant."""
        return self.value.kind

    @classmethod
    def from_json(cls, x: Any) -> 'XmlBody':
        if isinstance(x, List) and len(x) == 2:
            cons = x[0]
            if cons == 'XmlText':
                return cls(XmlText(StringWrap.from_json(x[1])))
            if cons == 'XmlExpr':
                return cls(XmlExpr(ExprNullableBracket.from_json(x[1])))
            if cons == 'XmlXml':
                return cls(XmlXml(Xml.from_json(x[1])))
            _atd_bad_json('XmlBody', x)
        _atd_bad_json('XmlBody', x)

    def to_json(self) -> Any:
        return self.value.to_json()

    @classmethod
    def from_json_string(cls, x: str) -> 'XmlBody':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)


@dataclass
class Program:
    """Original type: program"""

    value: List[Item]

    @classmethod
    def from_json(cls, x: Any) -> 'Program':
        return cls(_atd_read_list(Item.from_json)(x))

    def to_json(self) -> Any:
        return _atd_write_list((lambda x: x.to_json()))(self.value)

    @classmethod
    def from_json_string(cls, x: str) -> 'Program':
        return cls.from_json(json.loads(x))

    def to_json_string(self, **kw: Any) -> str:
        return json.dumps(self.to_json(), **kw)
