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

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

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

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 _Identity:
    value: Any
    def to_json(self) -> Any:
        return self.value
class Abstract:
    @classmethod
    def from_json(cls, x: Any) -> Any:
        return _Identity(x)



@dataclass
class ID:
    """Original type: unique_id_type = [ ... | ID | ... ]"""

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

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

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


@dataclass
class AST:
    """Original type: unique_id_type = [ ... | AST | ... ]"""

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

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

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


@dataclass(frozen=True)
class UniqueIdType:
    """Original type: unique_id_type = [ ... ]"""

    value: Union[ID, AST]

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

    @classmethod
    def from_json(cls, x: Any) -> 'UniqueIdType':
        if isinstance(x, str):
            if x == 'id':
                return cls(ID())
            if x == 'AST':
                return cls(AST())
            _atd_bad_json('UniqueIdType', x)
        _atd_bad_json('UniqueIdType', x)

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

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

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


@dataclass(frozen=True)
class UniqueId:
    """Original type: unique_id = { ... }"""

    type_: UniqueIdType
    md5sum: Optional[str] = None
    sid: Optional[int] = None

    @classmethod
    def from_json(cls, x: Any) -> 'UniqueId':
        if isinstance(x, dict):
            return cls(
                type_=UniqueIdType.from_json(x['type']) if 'type' in x else _atd_missing_json_field('UniqueId', 'type'),
                md5sum=_atd_read_string(x['md5sum']) if 'md5sum' in x else None,
                sid=_atd_read_int(x['sid']) if 'sid' in x else None,
            )
        else:
            _atd_bad_json('UniqueId', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['type'] = (lambda x: x.to_json())(self.type_)
        if self.md5sum is not None:
            res['md5sum'] = _atd_write_string(self.md5sum)
        if self.sid is not None:
            res['sid'] = _atd_write_int(self.sid)
        return res

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

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


@dataclass(frozen=True)
class RuleId:
    """Original type: rule_id"""

    value: str

    @classmethod
    def from_json(cls, x: Any) -> 'RuleId':
        return cls(_atd_read_string(x))

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

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

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


@dataclass(frozen=True)
class RuleTimes:
    """Original type: rule_times = { ... }"""

    rule_id: RuleId
    parse_time: float
    match_time: float

    @classmethod
    def from_json(cls, x: Any) -> 'RuleTimes':
        if isinstance(x, dict):
            return cls(
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else _atd_missing_json_field('RuleTimes', 'rule_id'),
                parse_time=_atd_read_float(x['parse_time']) if 'parse_time' in x else _atd_missing_json_field('RuleTimes', 'parse_time'),
                match_time=_atd_read_float(x['match_time']) if 'match_time' in x else _atd_missing_json_field('RuleTimes', 'match_time'),
            )
        else:
            _atd_bad_json('RuleTimes', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        res['parse_time'] = _atd_write_float(self.parse_time)
        res['match_time'] = _atd_write_float(self.match_time)
        return res

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

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


@dataclass(frozen=True)
class TargetTime:
    """Original type: target_time = { ... }"""

    path: str
    rule_times: List[RuleTimes]
    run_time: float

    @classmethod
    def from_json(cls, x: Any) -> 'TargetTime':
        if isinstance(x, dict):
            return cls(
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('TargetTime', 'path'),
                rule_times=_atd_read_list(RuleTimes.from_json)(x['rule_times']) if 'rule_times' in x else _atd_missing_json_field('TargetTime', 'rule_times'),
                run_time=_atd_read_float(x['run_time']) if 'run_time' in x else _atd_missing_json_field('TargetTime', 'run_time'),
            )
        else:
            _atd_bad_json('TargetTime', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['path'] = _atd_write_string(self.path)
        res['rule_times'] = _atd_write_list((lambda x: x.to_json()))(self.rule_times)
        res['run_time'] = _atd_write_float(self.run_time)
        return res

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

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


@dataclass(frozen=True, order=True)
class Position:
    """Original type: position = { ... }"""

    line: int
    col: int
    offset: int

    @classmethod
    def from_json(cls, x: Any) -> 'Position':
        if isinstance(x, dict):
            return cls(
                line=_atd_read_int(x['line']) if 'line' in x else _atd_missing_json_field('Position', 'line'),
                col=_atd_read_int(x['col']) if 'col' in x else _atd_missing_json_field('Position', 'col'),
                offset=_atd_read_int(x['offset']) if 'offset' in x else _atd_missing_json_field('Position', 'offset'),
            )
        else:
            _atd_bad_json('Position', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['line'] = _atd_write_int(self.line)
        res['col'] = _atd_write_int(self.col)
        res['offset'] = _atd_write_int(self.offset)
        return res

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

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


@dataclass(frozen=True)
class SvalueValue:
    """Original type: svalue_value = { ... }"""

    svalue_abstract_content: str
    svalue_start: Optional[Position] = None
    svalue_end: Optional[Position] = None

    @classmethod
    def from_json(cls, x: Any) -> 'SvalueValue':
        if isinstance(x, dict):
            return cls(
                svalue_abstract_content=_atd_read_string(x['svalue_abstract_content']) if 'svalue_abstract_content' in x else _atd_missing_json_field('SvalueValue', 'svalue_abstract_content'),
                svalue_start=Position.from_json(x['svalue_start']) if 'svalue_start' in x else None,
                svalue_end=Position.from_json(x['svalue_end']) if 'svalue_end' in x else None,
            )
        else:
            _atd_bad_json('SvalueValue', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['svalue_abstract_content'] = _atd_write_string(self.svalue_abstract_content)
        if self.svalue_start is not None:
            res['svalue_start'] = (lambda x: x.to_json())(self.svalue_start)
        if self.svalue_end is not None:
            res['svalue_end'] = (lambda x: x.to_json())(self.svalue_end)
        return res

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

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


@dataclass
class ExcludedByConfig:
    """Original type: skip_reason = [ ... | Excluded_by_config | ... ]"""

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

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

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


@dataclass
class WrongLanguage:
    """Original type: skip_reason = [ ... | Wrong_language | ... ]"""

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

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

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


@dataclass
class TooBig:
    """Original type: skip_reason = [ ... | Too_big | ... ]"""

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

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

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


@dataclass
class Minified:
    """Original type: skip_reason = [ ... | Minified | ... ]"""

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

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

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


@dataclass
class Binary:
    """Original type: skip_reason = [ ... | Binary | ... ]"""

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

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

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


@dataclass
class IrrelevantRule:
    """Original type: skip_reason = [ ... | Irrelevant_rule | ... ]"""

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

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

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


@dataclass
class TooManyMatches:
    """Original type: skip_reason = [ ... | Too_many_matches | ... ]"""

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

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

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


@dataclass(frozen=True)
class SkipReason:
    """Original type: skip_reason = [ ... ]"""

    value: Union[ExcludedByConfig, WrongLanguage, TooBig, Minified, Binary, IrrelevantRule, TooManyMatches]

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

    @classmethod
    def from_json(cls, x: Any) -> 'SkipReason':
        if isinstance(x, str):
            if x == 'excluded_by_config':
                return cls(ExcludedByConfig())
            if x == 'wrong_language':
                return cls(WrongLanguage())
            if x == 'too_big':
                return cls(TooBig())
            if x == 'minified':
                return cls(Minified())
            if x == 'binary':
                return cls(Binary())
            if x == 'irrelevant_rule':
                return cls(IrrelevantRule())
            if x == 'too_many_matches':
                return cls(TooManyMatches())
            _atd_bad_json('SkipReason', x)
        _atd_bad_json('SkipReason', x)

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

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

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


@dataclass(frozen=True)
class SkippedTarget:
    """Original type: skipped_target = { ... }"""

    path: str
    reason: SkipReason
    details: str
    rule_id: Optional[RuleId] = None

    @classmethod
    def from_json(cls, x: Any) -> 'SkippedTarget':
        if isinstance(x, dict):
            return cls(
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('SkippedTarget', 'path'),
                reason=SkipReason.from_json(x['reason']) if 'reason' in x else _atd_missing_json_field('SkippedTarget', 'reason'),
                details=_atd_read_string(x['details']) if 'details' in x else _atd_missing_json_field('SkippedTarget', 'details'),
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else None,
            )
        else:
            _atd_bad_json('SkippedTarget', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['path'] = _atd_write_string(self.path)
        res['reason'] = (lambda x: x.to_json())(self.reason)
        res['details'] = _atd_write_string(self.details)
        if self.rule_id is not None:
            res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        return res

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

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


@dataclass(frozen=True)
class SkippedRule:
    """Original type: skipped_rule = { ... }"""

    rule_id: RuleId
    details: str
    position: Position

    @classmethod
    def from_json(cls, x: Any) -> 'SkippedRule':
        if isinstance(x, dict):
            return cls(
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else _atd_missing_json_field('SkippedRule', 'rule_id'),
                details=_atd_read_string(x['details']) if 'details' in x else _atd_missing_json_field('SkippedRule', 'details'),
                position=Position.from_json(x['position']) if 'position' in x else _atd_missing_json_field('SkippedRule', 'position'),
            )
        else:
            _atd_bad_json('SkippedRule', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        res['details'] = _atd_write_string(self.details)
        res['position'] = (lambda x: x.to_json())(self.position)
        return res

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

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


@dataclass
class Semver:
    """Original type: semver"""

    value: str

    @classmethod
    def from_json(cls, x: Any) -> 'Semver':
        return cls(_atd_read_string(x))

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

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

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


@dataclass
class RuleIdDict:
    """Original type: rule_id_dict = { ... }"""

    id: RuleId

    @classmethod
    def from_json(cls, x: Any) -> 'RuleIdDict':
        if isinstance(x, dict):
            return cls(
                id=RuleId.from_json(x['id']) if 'id' in x else _atd_missing_json_field('RuleIdDict', 'id'),
            )
        else:
            _atd_bad_json('RuleIdDict', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['id'] = (lambda x: x.to_json())(self.id)
        return res

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

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


@dataclass
class RawJson:
    """Original type: raw_json"""

    value: Any

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

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

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

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


@dataclass
class PositionBis:
    """Original type: position_bis = { ... }"""

    line: int
    col: int

    @classmethod
    def from_json(cls, x: Any) -> 'PositionBis':
        if isinstance(x, dict):
            return cls(
                line=_atd_read_int(x['line']) if 'line' in x else _atd_missing_json_field('PositionBis', 'line'),
                col=_atd_read_int(x['col']) if 'col' in x else _atd_missing_json_field('PositionBis', 'col'),
            )
        else:
            _atd_bad_json('PositionBis', x)

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

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

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


@dataclass(frozen=True)
class MetavarValue:
    """Original type: metavar_value = { ... }"""

    start: Position
    end: Position
    abstract_content: str
    unique_id: UniqueId
    propagated_value: Optional[SvalueValue] = None

    @classmethod
    def from_json(cls, x: Any) -> 'MetavarValue':
        if isinstance(x, dict):
            return cls(
                start=Position.from_json(x['start']) if 'start' in x else _atd_missing_json_field('MetavarValue', 'start'),
                end=Position.from_json(x['end']) if 'end' in x else _atd_missing_json_field('MetavarValue', 'end'),
                abstract_content=_atd_read_string(x['abstract_content']) if 'abstract_content' in x else _atd_missing_json_field('MetavarValue', 'abstract_content'),
                unique_id=UniqueId.from_json(x['unique_id']) if 'unique_id' in x else _atd_missing_json_field('MetavarValue', 'unique_id'),
                propagated_value=SvalueValue.from_json(x['propagated_value']) if 'propagated_value' in x else None,
            )
        else:
            _atd_bad_json('MetavarValue', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['start'] = (lambda x: x.to_json())(self.start)
        res['end'] = (lambda x: x.to_json())(self.end)
        res['abstract_content'] = _atd_write_string(self.abstract_content)
        res['unique_id'] = (lambda x: x.to_json())(self.unique_id)
        if self.propagated_value is not None:
            res['propagated_value'] = (lambda x: x.to_json())(self.propagated_value)
        return res

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

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


@dataclass
class Metavars:
    """Original type: metavars"""

    value: Dict[str, MetavarValue]

    @classmethod
    def from_json(cls, x: Any) -> 'Metavars':
        return cls(_atd_read_assoc_object_into_dict(MetavarValue.from_json)(x))

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

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

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


@dataclass(frozen=True)
class Location:
    """Original type: location = { ... }"""

    path: str
    start: Position
    end: Position

    @classmethod
    def from_json(cls, x: Any) -> 'Location':
        if isinstance(x, dict):
            return cls(
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('Location', 'path'),
                start=Position.from_json(x['start']) if 'start' in x else _atd_missing_json_field('Location', 'start'),
                end=Position.from_json(x['end']) if 'end' in x else _atd_missing_json_field('Location', 'end'),
            )
        else:
            _atd_bad_json('Location', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['path'] = _atd_write_string(self.path)
        res['start'] = (lambda x: x.to_json())(self.start)
        res['end'] = (lambda x: x.to_json())(self.end)
        return res

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

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


@dataclass
class LegacySpan:
    """Original type: legacy_span = { ... }"""

    config_start: Optional[PositionBis]
    config_end: Optional[PositionBis]
    config_path: Optional[List[str]]

    @classmethod
    def from_json(cls, x: Any) -> 'LegacySpan':
        if isinstance(x, dict):
            return cls(
                config_start=_atd_read_nullable(PositionBis.from_json)(x['config_start']) if 'config_start' in x else _atd_missing_json_field('LegacySpan', 'config_start'),
                config_end=_atd_read_nullable(PositionBis.from_json)(x['config_end']) if 'config_end' in x else _atd_missing_json_field('LegacySpan', 'config_end'),
                config_path=_atd_read_nullable(_atd_read_list(_atd_read_string))(x['config_path']) if 'config_path' in x else _atd_missing_json_field('LegacySpan', 'config_path'),
            )
        else:
            _atd_bad_json('LegacySpan', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['config_start'] = _atd_write_nullable((lambda x: x.to_json()))(self.config_start)
        res['config_end'] = _atd_write_nullable((lambda x: x.to_json()))(self.config_end)
        res['config_path'] = _atd_write_nullable(_atd_write_list(_atd_write_string))(self.config_path)
        return res

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

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


@dataclass
class FixRegex:
    """Original type: fix_regex = { ... }"""

    regex: str
    replacement: str
    count: Optional[int] = None

    @classmethod
    def from_json(cls, x: Any) -> 'FixRegex':
        if isinstance(x, dict):
            return cls(
                regex=_atd_read_string(x['regex']) if 'regex' in x else _atd_missing_json_field('FixRegex', 'regex'),
                replacement=_atd_read_string(x['replacement']) if 'replacement' in x else _atd_missing_json_field('FixRegex', 'replacement'),
                count=_atd_read_int(x['count']) if 'count' in x else None,
            )
        else:
            _atd_bad_json('FixRegex', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['regex'] = _atd_write_string(self.regex)
        res['replacement'] = _atd_write_string(self.replacement)
        if self.count is not None:
            res['count'] = _atd_write_int(self.count)
        return res

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

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


@dataclass
class Finding:
    """Original type: finding = { ... }"""

    check_id: RuleId
    path: str
    line: int
    column: int
    end_line: int
    end_column: int
    message: str
    severity: int
    index: int
    commit_date: str
    syntactic_id: str
    metadata: RawJson
    is_blocking: bool
    fixed_lines: Optional[List[str]] = None

    @classmethod
    def from_json(cls, x: Any) -> 'Finding':
        if isinstance(x, dict):
            return cls(
                check_id=RuleId.from_json(x['check_id']) if 'check_id' in x else _atd_missing_json_field('Finding', 'check_id'),
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('Finding', 'path'),
                line=_atd_read_int(x['line']) if 'line' in x else _atd_missing_json_field('Finding', 'line'),
                column=_atd_read_int(x['column']) if 'column' in x else _atd_missing_json_field('Finding', 'column'),
                end_line=_atd_read_int(x['end_line']) if 'end_line' in x else _atd_missing_json_field('Finding', 'end_line'),
                end_column=_atd_read_int(x['end_column']) if 'end_column' in x else _atd_missing_json_field('Finding', 'end_column'),
                message=_atd_read_string(x['message']) if 'message' in x else _atd_missing_json_field('Finding', 'message'),
                severity=_atd_read_int(x['severity']) if 'severity' in x else _atd_missing_json_field('Finding', 'severity'),
                index=_atd_read_int(x['index']) if 'index' in x else _atd_missing_json_field('Finding', 'index'),
                commit_date=_atd_read_string(x['commit_date']) if 'commit_date' in x else _atd_missing_json_field('Finding', 'commit_date'),
                syntactic_id=_atd_read_string(x['syntactic_id']) if 'syntactic_id' in x else _atd_missing_json_field('Finding', 'syntactic_id'),
                metadata=RawJson.from_json(x['metadata']) if 'metadata' in x else _atd_missing_json_field('Finding', 'metadata'),
                is_blocking=_atd_read_bool(x['is_blocking']) if 'is_blocking' in x else _atd_missing_json_field('Finding', 'is_blocking'),
                fixed_lines=_atd_read_list(_atd_read_string)(x['fixed_lines']) if 'fixed_lines' in x else None,
            )
        else:
            _atd_bad_json('Finding', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['check_id'] = (lambda x: x.to_json())(self.check_id)
        res['path'] = _atd_write_string(self.path)
        res['line'] = _atd_write_int(self.line)
        res['column'] = _atd_write_int(self.column)
        res['end_line'] = _atd_write_int(self.end_line)
        res['end_column'] = _atd_write_int(self.end_column)
        res['message'] = _atd_write_string(self.message)
        res['severity'] = _atd_write_int(self.severity)
        res['index'] = _atd_write_int(self.index)
        res['commit_date'] = _atd_write_string(self.commit_date)
        res['syntactic_id'] = _atd_write_string(self.syntactic_id)
        res['metadata'] = (lambda x: x.to_json())(self.metadata)
        res['is_blocking'] = _atd_write_bool(self.is_blocking)
        if self.fixed_lines is not None:
            res['fixed_lines'] = _atd_write_list(_atd_write_string)(self.fixed_lines)
        return res

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

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


@dataclass
class ErrorSpan:
    """Original type: error_span = { ... }"""

    config_start: Optional[PositionBis]
    config_end: Optional[PositionBis]
    config_path: Optional[List[str]]
    file: Optional[str] = None
    start: Optional[PositionBis] = None
    end: Optional[PositionBis] = None
    source_hash: Optional[str] = None
    context_start: Optional[Optional[PositionBis]] = None
    context_end: Optional[Optional[PositionBis]] = None

    @classmethod
    def from_json(cls, x: Any) -> 'ErrorSpan':
        if isinstance(x, dict):
            return cls(
                config_start=_atd_read_nullable(PositionBis.from_json)(x['config_start']) if 'config_start' in x else _atd_missing_json_field('ErrorSpan', 'config_start'),
                config_end=_atd_read_nullable(PositionBis.from_json)(x['config_end']) if 'config_end' in x else _atd_missing_json_field('ErrorSpan', 'config_end'),
                config_path=_atd_read_nullable(_atd_read_list(_atd_read_string))(x['config_path']) if 'config_path' in x else _atd_missing_json_field('ErrorSpan', 'config_path'),
                file=_atd_read_string(x['file']) if 'file' in x else None,
                start=PositionBis.from_json(x['start']) if 'start' in x else None,
                end=PositionBis.from_json(x['end']) if 'end' in x else None,
                source_hash=_atd_read_string(x['source_hash']) if 'source_hash' in x else None,
                context_start=_atd_read_nullable(PositionBis.from_json)(x['context_start']) if 'context_start' in x else None,
                context_end=_atd_read_nullable(PositionBis.from_json)(x['context_end']) if 'context_end' in x else None,
            )
        else:
            _atd_bad_json('ErrorSpan', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['config_start'] = _atd_write_nullable((lambda x: x.to_json()))(self.config_start)
        res['config_end'] = _atd_write_nullable((lambda x: x.to_json()))(self.config_end)
        res['config_path'] = _atd_write_nullable(_atd_write_list(_atd_write_string))(self.config_path)
        if self.file is not None:
            res['file'] = _atd_write_string(self.file)
        if self.start is not None:
            res['start'] = (lambda x: x.to_json())(self.start)
        if self.end is not None:
            res['end'] = (lambda x: x.to_json())(self.end)
        if self.source_hash is not None:
            res['source_hash'] = _atd_write_string(self.source_hash)
        if self.context_start is not None:
            res['context_start'] = _atd_write_nullable((lambda x: x.to_json()))(self.context_start)
        if self.context_end is not None:
            res['context_end'] = _atd_write_nullable((lambda x: x.to_json()))(self.context_end)
        return res

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

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


@dataclass(frozen=True)
class CveResult:
    """Original type: cve_result = { ... }"""

    url: str
    filename: str
    funcnames: List[str]

    @classmethod
    def from_json(cls, x: Any) -> 'CveResult':
        if isinstance(x, dict):
            return cls(
                url=_atd_read_string(x['url']) if 'url' in x else _atd_missing_json_field('CveResult', 'url'),
                filename=_atd_read_string(x['filename']) if 'filename' in x else _atd_missing_json_field('CveResult', 'filename'),
                funcnames=_atd_read_list(_atd_read_string)(x['funcnames']) if 'funcnames' in x else _atd_missing_json_field('CveResult', 'funcnames'),
            )
        else:
            _atd_bad_json('CveResult', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['url'] = _atd_write_string(self.url)
        res['filename'] = _atd_write_string(self.filename)
        res['funcnames'] = _atd_write_list(_atd_write_string)(self.funcnames)
        return res

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

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


@dataclass(frozen=True)
class CveResults:
    """Original type: cve_results"""

    value: List[CveResult]

    @classmethod
    def from_json(cls, x: Any) -> 'CveResults':
        return cls(_atd_read_list(CveResult.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) -> 'CveResults':
        return cls.from_json(json.loads(x))

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


@dataclass(frozen=True)
class CoreTiming:
    """Original type: core_timing = { ... }"""

    targets: List[TargetTime]
    rules: List[RuleId]
    rules_parse_time: Optional[float] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CoreTiming':
        if isinstance(x, dict):
            return cls(
                targets=_atd_read_list(TargetTime.from_json)(x['targets']) if 'targets' in x else _atd_missing_json_field('CoreTiming', 'targets'),
                rules=_atd_read_list(RuleId.from_json)(x['rules']) if 'rules' in x else _atd_missing_json_field('CoreTiming', 'rules'),
                rules_parse_time=_atd_read_float(x['rules_parse_time']) if 'rules_parse_time' in x else None,
            )
        else:
            _atd_bad_json('CoreTiming', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['targets'] = _atd_write_list((lambda x: x.to_json()))(self.targets)
        res['rules'] = _atd_write_list((lambda x: x.to_json()))(self.rules)
        if self.rules_parse_time is not None:
            res['rules_parse_time'] = _atd_write_float(self.rules_parse_time)
        return res

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

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


@dataclass(frozen=True)
class CoreStats:
    """Original type: core_stats = { ... }"""

    okfiles: int
    errorfiles: int

    @classmethod
    def from_json(cls, x: Any) -> 'CoreStats':
        if isinstance(x, dict):
            return cls(
                okfiles=_atd_read_int(x['okfiles']) if 'okfiles' in x else _atd_missing_json_field('CoreStats', 'okfiles'),
                errorfiles=_atd_read_int(x['errorfiles']) if 'errorfiles' in x else _atd_missing_json_field('CoreStats', 'errorfiles'),
            )
        else:
            _atd_bad_json('CoreStats', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['okfiles'] = _atd_write_int(self.okfiles)
        res['errorfiles'] = _atd_write_int(self.errorfiles)
        return res

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

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


@dataclass
class Error:
    """Original type: core_severity = [ ... | Error | ... ]"""

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

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

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


@dataclass
class Warning:
    """Original type: core_severity = [ ... | Warning | ... ]"""

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

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

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


@dataclass(frozen=True)
class CoreSeverity:
    """Original type: core_severity = [ ... ]"""

    value: Union[Error, Warning]

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

    @classmethod
    def from_json(cls, x: Any) -> 'CoreSeverity':
        if isinstance(x, str):
            if x == 'error':
                return cls(Error())
            if x == 'warning':
                return cls(Warning())
            _atd_bad_json('CoreSeverity', x)
        _atd_bad_json('CoreSeverity', x)

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

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

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


@dataclass(frozen=True)
class CoreMatchExtra:
    """Original type: core_match_extra = { ... }"""

    metavars: Metavars
    message: Optional[str] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CoreMatchExtra':
        if isinstance(x, dict):
            return cls(
                metavars=Metavars.from_json(x['metavars']) if 'metavars' in x else _atd_missing_json_field('CoreMatchExtra', 'metavars'),
                message=_atd_read_string(x['message']) if 'message' in x else None,
            )
        else:
            _atd_bad_json('CoreMatchExtra', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['metavars'] = (lambda x: x.to_json())(self.metavars)
        if self.message is not None:
            res['message'] = _atd_write_string(self.message)
        return res

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

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


@dataclass(frozen=True)
class CoreMatch:
    """Original type: core_match = { ... }"""

    rule_id: RuleId
    location: Location
    extra: CoreMatchExtra

    @classmethod
    def from_json(cls, x: Any) -> 'CoreMatch':
        if isinstance(x, dict):
            return cls(
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else _atd_missing_json_field('CoreMatch', 'rule_id'),
                location=Location.from_json(x['location']) if 'location' in x else _atd_missing_json_field('CoreMatch', 'location'),
                extra=CoreMatchExtra.from_json(x['extra']) if 'extra' in x else _atd_missing_json_field('CoreMatch', 'extra'),
            )
        else:
            _atd_bad_json('CoreMatch', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        res['location'] = (lambda x: x.to_json())(self.location)
        res['extra'] = (lambda x: x.to_json())(self.extra)
        return res

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

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


@dataclass
class LexicalError:
    """Original type: core_error_kind = [ ... | LexicalError | ... ]"""

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

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

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


@dataclass
class ParseError:
    """Original type: core_error_kind = [ ... | ParseError | ... ]"""

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

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

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


@dataclass
class SpecifiedParseError:
    """Original type: core_error_kind = [ ... | SpecifiedParseError | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Other syntax error'

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


@dataclass
class AstBuilderError:
    """Original type: core_error_kind = [ ... | AstBuilderError | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'AST builder error'

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


@dataclass
class RuleParseError:
    """Original type: core_error_kind = [ ... | RuleParseError | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Rule parse error'

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


@dataclass
class PatternParseError:
    """Original type: core_error_kind = [ ... | PatternParseError | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Pattern parse error'

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


@dataclass
class InvalidYaml:
    """Original type: core_error_kind = [ ... | InvalidYaml | ... ]"""

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

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

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


@dataclass
class MatchingError:
    """Original type: core_error_kind = [ ... | MatchingError | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Internal matching error'

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


@dataclass
class SemgrepMatchFound:
    """Original type: core_error_kind = [ ... | SemgrepMatchFound | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Semgrep match found'

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


@dataclass
class TooManyMatches_:
    """Original type: core_error_kind = [ ... | TooManyMatches | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Too many matches'

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


@dataclass
class FatalError:
    """Original type: core_error_kind = [ ... | FatalError | ... ]"""

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

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

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


@dataclass
class Timeout:
    """Original type: core_error_kind = [ ... | Timeout | ... ]"""

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

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

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


@dataclass
class OutOfMemory:
    """Original type: core_error_kind = [ ... | OutOfMemory | ... ]"""

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

    @staticmethod
    def to_json() -> Any:
        return 'Out of memory'

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


@dataclass(frozen=True, order=True)
class CoreErrorKind:
    """Original type: core_error_kind = [ ... ]"""

    value: Union[LexicalError, ParseError, SpecifiedParseError, AstBuilderError, RuleParseError, PatternParseError, InvalidYaml, MatchingError, SemgrepMatchFound, TooManyMatches_, FatalError, Timeout, OutOfMemory]

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

    @classmethod
    def from_json(cls, x: Any) -> 'CoreErrorKind':
        if isinstance(x, str):
            if x == 'Lexical error':
                return cls(LexicalError())
            if x == 'Syntax error':
                return cls(ParseError())
            if x == 'Other syntax error':
                return cls(SpecifiedParseError())
            if x == 'AST builder error':
                return cls(AstBuilderError())
            if x == 'Rule parse error':
                return cls(RuleParseError())
            if x == 'Pattern parse error':
                return cls(PatternParseError())
            if x == 'Invalid YAML':
                return cls(InvalidYaml())
            if x == 'Internal matching error':
                return cls(MatchingError())
            if x == 'Semgrep match found':
                return cls(SemgrepMatchFound())
            if x == 'Too many matches':
                return cls(TooManyMatches_())
            if x == 'Fatal error':
                return cls(FatalError())
            if x == 'Timeout':
                return cls(Timeout())
            if x == 'Out of memory':
                return cls(OutOfMemory())
            _atd_bad_json('CoreErrorKind', x)
        _atd_bad_json('CoreErrorKind', x)

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

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

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


@dataclass(frozen=True)
class CoreError:
    """Original type: core_error = { ... }"""

    error_type: CoreErrorKind
    severity: CoreSeverity
    location: Location
    message: str
    rule_id: Optional[RuleId] = None
    details: Optional[str] = None
    yaml_path: Optional[List[str]] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CoreError':
        if isinstance(x, dict):
            return cls(
                error_type=CoreErrorKind.from_json(x['error_type']) if 'error_type' in x else _atd_missing_json_field('CoreError', 'error_type'),
                severity=CoreSeverity.from_json(x['severity']) if 'severity' in x else _atd_missing_json_field('CoreError', 'severity'),
                location=Location.from_json(x['location']) if 'location' in x else _atd_missing_json_field('CoreError', 'location'),
                message=_atd_read_string(x['message']) if 'message' in x else _atd_missing_json_field('CoreError', 'message'),
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else None,
                details=_atd_read_string(x['details']) if 'details' in x else None,
                yaml_path=_atd_read_list(_atd_read_string)(x['yaml_path']) if 'yaml_path' in x else None,
            )
        else:
            _atd_bad_json('CoreError', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['error_type'] = (lambda x: x.to_json())(self.error_type)
        res['severity'] = (lambda x: x.to_json())(self.severity)
        res['location'] = (lambda x: x.to_json())(self.location)
        res['message'] = _atd_write_string(self.message)
        if self.rule_id is not None:
            res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        if self.details is not None:
            res['details'] = _atd_write_string(self.details)
        if self.yaml_path is not None:
            res['yaml_path'] = _atd_write_list(_atd_write_string)(self.yaml_path)
        return res

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

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


@dataclass(frozen=True)
class CoreMatchResults:
    """Original type: core_match_results = { ... }"""

    matches: List[CoreMatch]
    errors: List[CoreError]
    skipped_targets: List[SkippedTarget]
    stats: CoreStats
    skipped_rules: Optional[List[SkippedRule]] = None
    time: Optional[CoreTiming] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CoreMatchResults':
        if isinstance(x, dict):
            return cls(
                matches=_atd_read_list(CoreMatch.from_json)(x['matches']) if 'matches' in x else _atd_missing_json_field('CoreMatchResults', 'matches'),
                errors=_atd_read_list(CoreError.from_json)(x['errors']) if 'errors' in x else _atd_missing_json_field('CoreMatchResults', 'errors'),
                skipped_targets=_atd_read_list(SkippedTarget.from_json)(x['skipped']) if 'skipped' in x else _atd_missing_json_field('CoreMatchResults', 'skipped'),
                stats=CoreStats.from_json(x['stats']) if 'stats' in x else _atd_missing_json_field('CoreMatchResults', 'stats'),
                skipped_rules=_atd_read_list(SkippedRule.from_json)(x['skipped_rules']) if 'skipped_rules' in x else None,
                time=CoreTiming.from_json(x['time']) if 'time' in x else None,
            )
        else:
            _atd_bad_json('CoreMatchResults', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['matches'] = _atd_write_list((lambda x: x.to_json()))(self.matches)
        res['errors'] = _atd_write_list((lambda x: x.to_json()))(self.errors)
        res['skipped'] = _atd_write_list((lambda x: x.to_json()))(self.skipped_targets)
        res['stats'] = (lambda x: x.to_json())(self.stats)
        if self.skipped_rules is not None:
            res['skipped_rules'] = _atd_write_list((lambda x: x.to_json()))(self.skipped_rules)
        if self.time is not None:
            res['time'] = (lambda x: x.to_json())(self.time)
        return res

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

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


@dataclass
class CliTargetTimes:
    """Original type: cli_target_times = { ... }"""

    path: str
    num_bytes: int
    match_times: List[float]
    parse_times: List[float]
    run_time: float

    @classmethod
    def from_json(cls, x: Any) -> 'CliTargetTimes':
        if isinstance(x, dict):
            return cls(
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('CliTargetTimes', 'path'),
                num_bytes=_atd_read_int(x['num_bytes']) if 'num_bytes' in x else _atd_missing_json_field('CliTargetTimes', 'num_bytes'),
                match_times=_atd_read_list(_atd_read_float)(x['match_times']) if 'match_times' in x else _atd_missing_json_field('CliTargetTimes', 'match_times'),
                parse_times=_atd_read_list(_atd_read_float)(x['parse_times']) if 'parse_times' in x else _atd_missing_json_field('CliTargetTimes', 'parse_times'),
                run_time=_atd_read_float(x['run_time']) if 'run_time' in x else _atd_missing_json_field('CliTargetTimes', 'run_time'),
            )
        else:
            _atd_bad_json('CliTargetTimes', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['path'] = _atd_write_string(self.path)
        res['num_bytes'] = _atd_write_int(self.num_bytes)
        res['match_times'] = _atd_write_list(_atd_write_float)(self.match_times)
        res['parse_times'] = _atd_write_list(_atd_write_float)(self.parse_times)
        res['run_time'] = _atd_write_float(self.run_time)
        return res

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

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


@dataclass
class CliTiming:
    """Original type: cli_timing = { ... }"""

    rules: List[RuleIdDict]
    rules_parse_time: float
    profiling_times: Dict[str, float]
    targets: List[CliTargetTimes]
    total_bytes: int

    @classmethod
    def from_json(cls, x: Any) -> 'CliTiming':
        if isinstance(x, dict):
            return cls(
                rules=_atd_read_list(RuleIdDict.from_json)(x['rules']) if 'rules' in x else _atd_missing_json_field('CliTiming', 'rules'),
                rules_parse_time=_atd_read_float(x['rules_parse_time']) if 'rules_parse_time' in x else _atd_missing_json_field('CliTiming', 'rules_parse_time'),
                profiling_times=_atd_read_assoc_object_into_dict(_atd_read_float)(x['profiling_times']) if 'profiling_times' in x else _atd_missing_json_field('CliTiming', 'profiling_times'),
                targets=_atd_read_list(CliTargetTimes.from_json)(x['targets']) if 'targets' in x else _atd_missing_json_field('CliTiming', 'targets'),
                total_bytes=_atd_read_int(x['total_bytes']) if 'total_bytes' in x else _atd_missing_json_field('CliTiming', 'total_bytes'),
            )
        else:
            _atd_bad_json('CliTiming', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['rules'] = _atd_write_list((lambda x: x.to_json()))(self.rules)
        res['rules_parse_time'] = _atd_write_float(self.rules_parse_time)
        res['profiling_times'] = _atd_write_assoc_dict_to_object(_atd_write_float)(self.profiling_times)
        res['targets'] = _atd_write_list((lambda x: x.to_json()))(self.targets)
        res['total_bytes'] = _atd_write_int(self.total_bytes)
        return res

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

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


@dataclass
class CliSkippedTarget:
    """Original type: cli_skipped_target = { ... }"""

    path: str
    reason: str

    @classmethod
    def from_json(cls, x: Any) -> 'CliSkippedTarget':
        if isinstance(x, dict):
            return cls(
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('CliSkippedTarget', 'path'),
                reason=_atd_read_string(x['reason']) if 'reason' in x else _atd_missing_json_field('CliSkippedTarget', 'reason'),
            )
        else:
            _atd_bad_json('CliSkippedTarget', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['path'] = _atd_write_string(self.path)
        res['reason'] = _atd_write_string(self.reason)
        return res

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

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


@dataclass
class CliPaths:
    """Original type: cli_paths = { ... }"""

    scanned: List[str]
    _comment: Optional[str] = None
    skipped: Optional[List[CliSkippedTarget]] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CliPaths':
        if isinstance(x, dict):
            return cls(
                scanned=_atd_read_list(_atd_read_string)(x['scanned']) if 'scanned' in x else _atd_missing_json_field('CliPaths', 'scanned'),
                _comment=_atd_read_string(x['_comment']) if '_comment' in x else None,
                skipped=_atd_read_list(CliSkippedTarget.from_json)(x['skipped']) if 'skipped' in x else None,
            )
        else:
            _atd_bad_json('CliPaths', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['scanned'] = _atd_write_list(_atd_write_string)(self.scanned)
        if self._comment is not None:
            res['_comment'] = _atd_write_string(self._comment)
        if self.skipped is not None:
            res['skipped'] = _atd_write_list((lambda x: x.to_json()))(self.skipped)
        return res

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

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


@dataclass
class CliOutputExtra:
    """Original type: cli_output_extra = { ... }"""

    paths: CliPaths
    time: Optional[CliTiming] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CliOutputExtra':
        if isinstance(x, dict):
            return cls(
                paths=CliPaths.from_json(x['paths']) if 'paths' in x else _atd_missing_json_field('CliOutputExtra', 'paths'),
                time=CliTiming.from_json(x['time']) if 'time' in x else None,
            )
        else:
            _atd_bad_json('CliOutputExtra', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['paths'] = (lambda x: x.to_json())(self.paths)
        if self.time is not None:
            res['time'] = (lambda x: x.to_json())(self.time)
        return res

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

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


@dataclass
class CliMatchExtra:
    """Original type: cli_match_extra = { ... }"""

    fingerprint: str
    lines: str
    message: str
    metadata: RawJson
    severity: str
    metavars: Optional[Metavars] = None
    fix: Optional[str] = None
    fix_regex: Optional[FixRegex] = None
    is_ignored: Optional[bool] = None
    dependency_match_only: Optional[bool] = None
    dependency_matches: Optional[RawJson] = None
    fixed_lines: Optional[List[str]] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CliMatchExtra':
        if isinstance(x, dict):
            return cls(
                fingerprint=_atd_read_string(x['fingerprint']) if 'fingerprint' in x else _atd_missing_json_field('CliMatchExtra', 'fingerprint'),
                lines=_atd_read_string(x['lines']) if 'lines' in x else _atd_missing_json_field('CliMatchExtra', 'lines'),
                message=_atd_read_string(x['message']) if 'message' in x else _atd_missing_json_field('CliMatchExtra', 'message'),
                metadata=RawJson.from_json(x['metadata']) if 'metadata' in x else _atd_missing_json_field('CliMatchExtra', 'metadata'),
                severity=_atd_read_string(x['severity']) if 'severity' in x else _atd_missing_json_field('CliMatchExtra', 'severity'),
                metavars=Metavars.from_json(x['metavars']) if 'metavars' in x else None,
                fix=_atd_read_string(x['fix']) if 'fix' in x else None,
                fix_regex=FixRegex.from_json(x['fix_regex']) if 'fix_regex' in x else None,
                is_ignored=_atd_read_bool(x['is_ignored']) if 'is_ignored' in x else None,
                dependency_match_only=_atd_read_bool(x['dependency_match_only']) if 'dependency_match_only' in x else None,
                dependency_matches=RawJson.from_json(x['dependency_matches']) if 'dependency_matches' in x else None,
                fixed_lines=_atd_read_list(_atd_read_string)(x['fixed_lines']) if 'fixed_lines' in x else None,
            )
        else:
            _atd_bad_json('CliMatchExtra', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['fingerprint'] = _atd_write_string(self.fingerprint)
        res['lines'] = _atd_write_string(self.lines)
        res['message'] = _atd_write_string(self.message)
        res['metadata'] = (lambda x: x.to_json())(self.metadata)
        res['severity'] = _atd_write_string(self.severity)
        if self.metavars is not None:
            res['metavars'] = (lambda x: x.to_json())(self.metavars)
        if self.fix is not None:
            res['fix'] = _atd_write_string(self.fix)
        if self.fix_regex is not None:
            res['fix_regex'] = (lambda x: x.to_json())(self.fix_regex)
        if self.is_ignored is not None:
            res['is_ignored'] = _atd_write_bool(self.is_ignored)
        if self.dependency_match_only is not None:
            res['dependency_match_only'] = _atd_write_bool(self.dependency_match_only)
        if self.dependency_matches is not None:
            res['dependency_matches'] = (lambda x: x.to_json())(self.dependency_matches)
        if self.fixed_lines is not None:
            res['fixed_lines'] = _atd_write_list(_atd_write_string)(self.fixed_lines)
        return res

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

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


@dataclass
class CliMatch:
    """Original type: cli_match = { ... }"""

    check_id: RuleId
    path: str
    start: Position
    end: Position
    extra: CliMatchExtra

    @classmethod
    def from_json(cls, x: Any) -> 'CliMatch':
        if isinstance(x, dict):
            return cls(
                check_id=RuleId.from_json(x['check_id']) if 'check_id' in x else _atd_missing_json_field('CliMatch', 'check_id'),
                path=_atd_read_string(x['path']) if 'path' in x else _atd_missing_json_field('CliMatch', 'path'),
                start=Position.from_json(x['start']) if 'start' in x else _atd_missing_json_field('CliMatch', 'start'),
                end=Position.from_json(x['end']) if 'end' in x else _atd_missing_json_field('CliMatch', 'end'),
                extra=CliMatchExtra.from_json(x['extra']) if 'extra' in x else _atd_missing_json_field('CliMatch', 'extra'),
            )
        else:
            _atd_bad_json('CliMatch', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['check_id'] = (lambda x: x.to_json())(self.check_id)
        res['path'] = _atd_write_string(self.path)
        res['start'] = (lambda x: x.to_json())(self.start)
        res['end'] = (lambda x: x.to_json())(self.end)
        res['extra'] = (lambda x: x.to_json())(self.extra)
        return res

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

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


@dataclass
class CliError:
    """Original type: cli_error = { ... }"""

    code: int
    level: str
    type_: str
    rule_id: Optional[RuleId] = None
    message: Optional[str] = None
    path: Optional[str] = None
    long_msg: Optional[str] = None
    short_msg: Optional[str] = None
    spans: Optional[List[ErrorSpan]] = None
    help: Optional[str] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CliError':
        if isinstance(x, dict):
            return cls(
                code=_atd_read_int(x['code']) if 'code' in x else _atd_missing_json_field('CliError', 'code'),
                level=_atd_read_string(x['level']) if 'level' in x else _atd_missing_json_field('CliError', 'level'),
                type_=_atd_read_string(x['type']) if 'type' in x else _atd_missing_json_field('CliError', 'type'),
                rule_id=RuleId.from_json(x['rule_id']) if 'rule_id' in x else None,
                message=_atd_read_string(x['message']) if 'message' in x else None,
                path=_atd_read_string(x['path']) if 'path' in x else None,
                long_msg=_atd_read_string(x['long_msg']) if 'long_msg' in x else None,
                short_msg=_atd_read_string(x['short_msg']) if 'short_msg' in x else None,
                spans=_atd_read_list(ErrorSpan.from_json)(x['spans']) if 'spans' in x else None,
                help=_atd_read_string(x['help']) if 'help' in x else None,
            )
        else:
            _atd_bad_json('CliError', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['code'] = _atd_write_int(self.code)
        res['level'] = _atd_write_string(self.level)
        res['type'] = _atd_write_string(self.type_)
        if self.rule_id is not None:
            res['rule_id'] = (lambda x: x.to_json())(self.rule_id)
        if self.message is not None:
            res['message'] = _atd_write_string(self.message)
        if self.path is not None:
            res['path'] = _atd_write_string(self.path)
        if self.long_msg is not None:
            res['long_msg'] = _atd_write_string(self.long_msg)
        if self.short_msg is not None:
            res['short_msg'] = _atd_write_string(self.short_msg)
        if self.spans is not None:
            res['spans'] = _atd_write_list((lambda x: x.to_json()))(self.spans)
        if self.help is not None:
            res['help'] = _atd_write_string(self.help)
        return res

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

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


@dataclass
class CliOutput:
    """Original type: cli_output = { ... }"""

    errors: List[CliError]
    results: List[CliMatch]
    paths: CliPaths
    version: Optional[Semver] = None
    time: Optional[CliTiming] = None

    @classmethod
    def from_json(cls, x: Any) -> 'CliOutput':
        if isinstance(x, dict):
            return cls(
                errors=_atd_read_list(CliError.from_json)(x['errors']) if 'errors' in x else _atd_missing_json_field('CliOutput', 'errors'),
                results=_atd_read_list(CliMatch.from_json)(x['results']) if 'results' in x else _atd_missing_json_field('CliOutput', 'results'),
                paths=CliPaths.from_json(x['paths']) if 'paths' in x else _atd_missing_json_field('CliOutput', 'paths'),
                version=Semver.from_json(x['version']) if 'version' in x else None,
                time=CliTiming.from_json(x['time']) if 'time' in x else None,
            )
        else:
            _atd_bad_json('CliOutput', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['errors'] = _atd_write_list((lambda x: x.to_json()))(self.errors)
        res['results'] = _atd_write_list((lambda x: x.to_json()))(self.results)
        res['paths'] = (lambda x: x.to_json())(self.paths)
        if self.version is not None:
            res['version'] = (lambda x: x.to_json())(self.version)
        if self.time is not None:
            res['time'] = (lambda x: x.to_json())(self.time)
        return res

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

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


@dataclass
class ApiScansFindings:
    """Original type: api_scans_findings = { ... }"""

    findings: List[Finding]
    token: Optional[str]
    gitlab_token: Optional[str]
    searched_paths: List[str]
    rule_ids: List[str]
    cai_ids: List[str]

    @classmethod
    def from_json(cls, x: Any) -> 'ApiScansFindings':
        if isinstance(x, dict):
            return cls(
                findings=_atd_read_list(Finding.from_json)(x['findings']) if 'findings' in x else _atd_missing_json_field('ApiScansFindings', 'findings'),
                token=_atd_read_nullable(_atd_read_string)(x['token']) if 'token' in x else _atd_missing_json_field('ApiScansFindings', 'token'),
                gitlab_token=_atd_read_nullable(_atd_read_string)(x['gitlab_token']) if 'gitlab_token' in x else _atd_missing_json_field('ApiScansFindings', 'gitlab_token'),
                searched_paths=_atd_read_list(_atd_read_string)(x['searched_paths']) if 'searched_paths' in x else _atd_missing_json_field('ApiScansFindings', 'searched_paths'),
                rule_ids=_atd_read_list(_atd_read_string)(x['rule_ids']) if 'rule_ids' in x else _atd_missing_json_field('ApiScansFindings', 'rule_ids'),
                cai_ids=_atd_read_list(_atd_read_string)(x['cai_ids']) if 'cai_ids' in x else _atd_missing_json_field('ApiScansFindings', 'cai_ids'),
            )
        else:
            _atd_bad_json('ApiScansFindings', x)

    def to_json(self) -> Any:
        res: Dict[str, Any] = {}
        res['findings'] = _atd_write_list((lambda x: x.to_json()))(self.findings)
        res['token'] = _atd_write_nullable(_atd_write_string)(self.token)
        res['gitlab_token'] = _atd_write_nullable(_atd_write_string)(self.gitlab_token)
        res['searched_paths'] = _atd_write_list(_atd_write_string)(self.searched_paths)
        res['rule_ids'] = _atd_write_list(_atd_write_string)(self.rule_ids)
        res['cai_ids'] = _atd_write_list(_atd_write_string)(self.cai_ids)
        return res

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

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