# Necessary for static type checking
if False:  # flake8: noqa
    from .parser import Loc
    from typing import Any, Optional, Union, List, Iterable

# This is autogenerated code. DO NOT change this manually.
# Run scripts/generate_ast.py to generate this file.


class Node(object):
    __slots__ = ()
    _fields = ()  # type: Iterable[str]
    loc = None  # type: Optional[Loc]


class Definition(Node):
    __slots__ = ()


class Document(Node):
    __slots__ = ("loc", "definitions")
    _fields = ("definitions",)

    def __init__(self, definitions, loc=None):
        # type: (Any, Optional[Loc]) -> None
        self.loc = loc
        self.definitions = definitions

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Document)
            and
            # self.loc == other.loc and
            self.definitions == other.definitions
        )

    def __repr__(self):
        # type: () -> str
        return ("Document(" "definitions={self.definitions!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> Document
        return type(self)(self.definitions, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class OperationDefinition(Definition):
    __slots__ = (
        "loc",
        "operation",
        "name",
        "variable_definitions",
        "directives",
        "selection_set",
    )
    _fields = (
        "operation",
        "name",
        "variable_definitions",
        "directives",
        "selection_set",
    )

    def __init__(
        self,
        operation,  # type: str
        selection_set,  # type: SelectionSet
        name=None,  # type: Optional[Name]
        #
        variable_definitions=None,  # type: Optional[List[VariableDefinition]]
        directives=None,  # type: Optional[List[Directive]]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.operation = operation
        self.name = name
        self.variable_definitions = variable_definitions
        self.directives = directives
        self.selection_set = selection_set

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, OperationDefinition)
            and
            # self.loc == other.loc and
            self.operation == other.operation
            and self.name == other.name
            and self.variable_definitions == other.variable_definitions
            and self.directives == other.directives
            and self.selection_set == other.selection_set
        )

    def __repr__(self):
        # type: () -> str
        return (
            "OperationDefinition("
            "operation={self.operation!r}"
            ", name={self.name!r}"
            ", variable_definitions={self.variable_definitions!r}"
            ", directives={self.directives!r}"
            ", selection_set={self.selection_set!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> OperationDefinition
        return type(self)(
            self.operation,
            self.selection_set,
            self.name,
            self.variable_definitions,
            self.directives,
            self.loc,
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class VariableDefinition(Node):
    __slots__ = ("loc", "variable", "type", "default_value")
    _fields = ("variable", "type", "default_value")

    def __init__(self, variable, type, default_value=None, loc=None):
        # type: (Variable, Any, Any, Optional[Loc]) -> None
        self.loc = loc
        self.variable = variable
        self.type = type
        self.default_value = default_value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, VariableDefinition)
            and
            # self.loc == other.loc and
            self.variable == other.variable
            and self.type == other.type
            and self.default_value == other.default_value
        )

    def __repr__(self):
        # type: () -> str
        return (
            "VariableDefinition("
            "variable={self.variable!r}"
            ", type={self.type!r}"
            ", default_value={self.default_value!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> VariableDefinition
        return type(self)(self.variable, self.type, self.default_value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class SelectionSet(Node):
    __slots__ = ("loc", "selections")
    _fields = ("selections",)

    def __init__(self, selections, loc=None):
        # type: (Any, Optional[Loc]) -> None
        self.loc = loc
        self.selections = selections

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, SelectionSet)
            and
            # self.loc == other.loc and
            self.selections == other.selections
        )

    def __repr__(self):
        # type: () -> str
        return ("SelectionSet(" "selections={self.selections!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> SelectionSet
        return type(self)(self.selections, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class Selection(Node):
    __slots__ = ()


class Field(Selection):
    __slots__ = ("loc", "alias", "name", "arguments", "directives", "selection_set")
    _fields = ("alias", "name", "arguments", "directives", "selection_set")

    def __init__(
        self,
        name,  # type: Name
        alias=None,  # type: Optional[Name]
        arguments=None,  # type: Optional[List[Argument]]
        directives=None,  # type: Optional[List[Directive]]
        selection_set=None,  # type: Optional[SelectionSet]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.alias = alias
        self.name = name
        self.arguments = arguments
        self.directives = directives
        self.selection_set = selection_set

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Field)
            and
            # self.loc == other.loc and
            self.alias == other.alias
            and self.name == other.name
            and self.arguments == other.arguments
            and self.directives == other.directives
            and self.selection_set == other.selection_set
        )

    def __repr__(self):
        # type: () -> str
        return (
            "Field("
            "alias={self.alias!r}"
            ", name={self.name!r}"
            ", arguments={self.arguments!r}"
            ", directives={self.directives!r}"
            ", selection_set={self.selection_set!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> Field
        return type(self)(
            self.name,
            self.alias,
            self.arguments,
            self.directives,
            self.selection_set,
            self.loc,
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class Argument(Node):
    __slots__ = ("loc", "name", "value")
    _fields = ("name", "value")

    def __init__(self, name, value, loc=None):
        # type: (Name, Any, Optional[Loc]) -> None
        self.loc = loc
        self.name = name
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Argument)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("Argument(" "name={self.name!r}" ", value={self.value!r}" ")").format(
            self=self
        )

    def __copy__(self):
        # type: () -> Argument
        return type(self)(self.name, self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class FragmentSpread(Selection):
    __slots__ = ("loc", "name", "directives")
    _fields = ("name", "directives")

    def __init__(
        self,
        name,  # type: Name
        directives=None,  # type: List[Directive]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, FragmentSpread)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "FragmentSpread("
            "name={self.name!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> FragmentSpread
        return type(self)(self.name, self.directives, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class InlineFragment(Selection):
    __slots__ = ("loc", "type_condition", "directives", "selection_set")
    _fields = ("type_condition", "directives", "selection_set")

    def __init__(
        self,
        type_condition,  # type: Optional[NamedType]
        selection_set,  # type: SelectionSet
        directives=None,  # type: Optional[List[Directive]]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.type_condition = type_condition
        self.directives = directives
        self.selection_set = selection_set

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, InlineFragment)
            and
            # self.loc == other.loc and
            self.type_condition == other.type_condition
            and self.directives == other.directives
            and self.selection_set == other.selection_set
        )

    def __repr__(self):
        # type: () -> str
        return (
            "InlineFragment("
            "type_condition={self.type_condition!r}"
            ", directives={self.directives!r}"
            ", selection_set={self.selection_set!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> InlineFragment
        return type(self)(
            self.type_condition, self.selection_set, self.directives, self.loc
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class FragmentDefinition(Definition):
    __slots__ = ("loc", "name", "type_condition", "directives", "selection_set")
    _fields = ("name", "type_condition", "directives", "selection_set")

    def __init__(
        self,
        name,  # type: Name
        type_condition,  # type: Optional[NamedType]
        selection_set,  # type: SelectionSet
        directives=None,  # type: Optional[List[Directive]]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.type_condition = type_condition
        self.directives = directives
        self.selection_set = selection_set

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, FragmentDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.type_condition == other.type_condition
            and self.directives == other.directives
            and self.selection_set == other.selection_set
        )

    def __repr__(self):
        # type: () -> str
        return (
            "FragmentDefinition("
            "name={self.name!r}"
            ", type_condition={self.type_condition!r}"
            ", directives={self.directives!r}"
            ", selection_set={self.selection_set!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> FragmentDefinition
        return type(self)(
            self.name,
            self.type_condition,
            self.selection_set,
            self.directives,
            self.loc,
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class Value(Node):
    __slots__ = ()


class Variable(Value):
    __slots__ = ("loc", "name")
    _fields = ("name",)

    def __init__(self, name, loc=None):
        # type: (Name, Optional[Loc]) -> None
        self.loc = loc
        self.name = name

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Variable)
            and self.name == other.name
            # and self.loc == other.loc
        )

    def __repr__(self):
        # type: () -> str
        return ("Variable(" "name={self.name!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> Variable
        return type(self)(self.name, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class IntValue(Value):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (str, Optional[Loc]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, IntValue)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("IntValue(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> IntValue
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class FloatValue(Value):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (str, Optional[Any]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, FloatValue)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("FloatValue(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> FloatValue
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class StringValue(Value):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (str, Optional[Loc]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, StringValue)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("StringValue(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> StringValue
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class BooleanValue(Value):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (bool, Optional[Loc]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, BooleanValue)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("BooleanValue(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> BooleanValue
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class EnumValue(Value):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (str, Optional[Loc]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, EnumValue)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("EnumValue(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> EnumValue
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ListValue(Value):
    __slots__ = ("loc", "values")
    _fields = ("values",)

    def __init__(self, values, loc=None):
        # type: (Any, Optional[Loc]) -> None
        self.loc = loc
        self.values = values

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ListValue)
            and
            # self.loc == other.loc and
            self.values == other.values
        )

    def __repr__(self):
        # type: () -> str
        return ("ListValue(" "values={self.values!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> ListValue
        return type(self)(self.values, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ObjectValue(Value):
    __slots__ = ("loc", "fields")
    _fields = ("fields",)

    def __init__(self, fields, loc=None):
        # type: (List[ObjectField], Optional[Loc]) -> None
        self.loc = loc
        self.fields = fields

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ObjectValue)
            and
            # self.loc == other.loc and
            self.fields == other.fields
        )

    def __repr__(self):
        # type: () -> str
        return ("ObjectValue(" "fields={self.fields!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> ObjectValue
        return type(self)(self.fields, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ObjectField(Node):
    __slots__ = ("loc", "name", "value")
    _fields = ("name", "value")

    def __init__(self, name, value, loc=None):
        # type: (Name, Any, Optional[Loc]) -> None
        self.loc = loc
        self.name = name
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ObjectField)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return (
            "ObjectField(" "name={self.name!r}" ", value={self.value!r}" ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> ObjectField
        return type(self)(self.name, self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class Directive(Node):
    __slots__ = ("loc", "name", "arguments")
    _fields = ("name", "arguments")

    def __init__(
        self,
        name,  # type: Name
        arguments=None,  # type: Optional[List[Argument]]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.arguments = arguments

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Directive)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.arguments == other.arguments
        )

    def __repr__(self):
        # type: () -> str
        return (
            "Directive(" "name={self.name!r}" ", arguments={self.arguments!r}" ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> Directive
        return type(self)(self.name, self.arguments, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class Type(Node):
    __slots__ = ()


class NamedType(Type):
    __slots__ = ("loc", "name")
    _fields = ("name",)

    def __init__(self, name, loc=None):
        # type: (Name, Optional[Loc]) -> None
        self.loc = loc
        self.name = name

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, NamedType)
            and
            # self.loc == other.loc and
            self.name == other.name
        )

    def __repr__(self):
        # type: () -> str
        return ("NamedType(" "name={self.name!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> NamedType
        return type(self)(self.name, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ListType(Type):
    __slots__ = ("loc", "type")
    _fields = ("type",)

    def __init__(self, type, loc=None):
        # type: (Union[NamedType, NonNullType], Optional[Loc]) -> None
        self.loc = loc
        self.type = type

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ListType)
            and
            # self.loc == other.loc and
            self.type == other.type
        )

    def __repr__(self):
        # type: () -> str
        return ("ListType(" "type={self.type!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> ListType
        return type(self)(self.type, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class NonNullType(Type):
    __slots__ = ("loc", "type")
    _fields = ("type",)

    def __init__(self, type, loc=None):
        # type: (Union[ListType, NamedType], Optional[Loc]) -> None
        self.loc = loc
        self.type = type

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, NonNullType)
            and
            # self.loc == other.loc and
            self.type == other.type
        )

    def __repr__(self):
        # type: () -> str
        return ("NonNullType(" "type={self.type!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> NonNullType
        return type(self)(self.type, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class Name(Node):
    __slots__ = ("loc", "value")
    _fields = ("value",)

    def __init__(self, value, loc=None):
        # type: (str, Optional[Loc]) -> None
        self.loc = loc
        self.value = value

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, Name)
            and
            # self.loc == other.loc and
            self.value == other.value
        )

    def __repr__(self):
        # type: () -> str
        return ("Name(" "value={self.value!r}" ")").format(self=self)

    def __copy__(self):
        # type: () -> Name
        return type(self)(self.value, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


# Type System Definition


class TypeDefinition(Node):
    pass


class TypeSystemDefinition(TypeDefinition):
    pass


class SchemaDefinition(TypeSystemDefinition):
    __slots__ = ("loc", "directives", "operation_types")
    _fields = ("operation_types",)

    def __init__(
        self,
        operation_types,  # type: List[OperationTypeDefinition]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.operation_types = operation_types
        self.loc = loc
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, SchemaDefinition)
            and self.operation_types == other.operation_types
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "SchemaDefinition("
            "operation_types={self.operation_types!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> SchemaDefinition
        return type(self)(self.operation_types, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class OperationTypeDefinition(Node):
    __slots__ = ("loc", "operation", "type")
    _fields = ("operation", "type")

    def __init__(self, operation, type, loc=None):
        # type: (str, NamedType, Optional[Loc]) -> None
        self.operation = operation
        self.type = type
        self.loc = loc

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, OperationTypeDefinition)
            and self.operation == other.operation
            and self.type == other.type
        )

    def __repr__(self):
        # type: () -> str
        return (
            "OperationTypeDefinition("
            "operation={self.operation!r}"
            ", type={self.type!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> OperationTypeDefinition
        return type(self)(self.operation, self.type, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ObjectTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "interfaces", "directives", "fields")
    _fields = ("name", "interfaces", "fields")

    def __init__(
        self,
        name,  # type: Name
        fields,  # type: List[FieldDefinition]
        interfaces=None,  # type: Optional[List[NamedType]]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.interfaces = interfaces
        self.fields = fields
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ObjectTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.interfaces == other.interfaces
            and self.fields == other.fields
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "ObjectTypeDefinition("
            "name={self.name!r}"
            ", interfaces={self.interfaces!r}"
            ", fields={self.fields!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> ObjectTypeDefinition
        return type(self)(
            self.name, self.fields, self.interfaces, self.loc, self.directives
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class FieldDefinition(Node):
    __slots__ = ("loc", "name", "arguments", "type", "directives")
    _fields = ("name", "arguments", "type")

    def __init__(
        self,
        name,  # type: Name
        arguments,  # type: List[InputValueDefinition]
        type,  # type: Union[NamedType, NonNullType, ListType]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.arguments = arguments
        self.type = type
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, FieldDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.arguments == other.arguments
            and self.type == other.type
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "FieldDefinition("
            "name={self.name!r}"
            ", arguments={self.arguments!r}"
            ", type={self.type!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> FieldDefinition
        return type(self)(
            self.name, self.arguments, self.type, self.loc, self.directives
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class InputValueDefinition(Node):
    __slots__ = ("loc", "name", "type", "default_value", "directives")
    _fields = ("name", "type", "default_value")

    def __init__(
        self,
        name,  # type: Name
        type,  # type: Union[NamedType, NonNullType, ListType]
        default_value=None,  # type: Any
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.type = type
        self.default_value = default_value
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, InputValueDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.type == other.type
            and self.default_value == other.default_value
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "InputValueDefinition("
            "name={self.name!r}"
            ", type={self.type!r}"
            ", default_value={self.default_value!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> InputValueDefinition
        return type(self)(
            self.name, self.type, self.default_value, self.loc, self.directives
        )

    def __hash__(self):
        # type: () -> int
        return id(self)


class InterfaceTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "fields", "directives")
    _fields = ("name", "fields")

    def __init__(
        self,
        name,  # type: Name
        fields,  # type: List[FieldDefinition]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.fields = fields
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, InterfaceTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.fields == other.fields
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "InterfaceTypeDefinition("
            "name={self.name!r}"
            ", fields={self.fields!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> InterfaceTypeDefinition
        return type(self)(self.name, self.fields, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class UnionTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "types", "directives")
    _fields = ("name", "types")

    def __init__(
        self,
        name,  # type: Name
        types,  # type: List[NamedType]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.types = types
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, UnionTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.types == other.types
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "UnionTypeDefinition("
            "name={self.name!r}"
            ", types={self.types!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> UnionTypeDefinition
        return type(self)(self.name, self.types, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class ScalarTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "directives")
    _fields = ("name",)

    def __init__(
        self,
        name,  # type: Name
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, ScalarTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "ScalarTypeDefinition("
            "name={self.name!r}"
            "directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> ScalarTypeDefinition
        return type(self)(self.name, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class EnumTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "values", "directives")
    _fields = ("name", "values")

    def __init__(
        self,
        name,  # type: Name
        values,  # type: List[EnumValueDefinition]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.values = values
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, EnumTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.values == other.values
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "EnumTypeDefinition("
            "name={self.name!r}"
            ", values={self.values!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> EnumTypeDefinition
        return type(self)(self.name, self.values, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class EnumValueDefinition(Node):
    __slots__ = ("loc", "name", "directives")
    _fields = ("name",)

    def __init__(
        self,
        name,  # type: Name
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, EnumValueDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "EnumValueDefinition("
            "name={self.name!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> EnumValueDefinition
        return type(self)(self.name, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class InputObjectTypeDefinition(TypeDefinition):
    __slots__ = ("loc", "name", "fields", "directives")
    _fields = ("name", "fields")

    def __init__(
        self,
        name,  # type: Name
        fields,  # type: List[InputValueDefinition]
        loc=None,  # type: Optional[Loc]
        directives=None,  # type: Optional[List[Directive]]
    ):
        # type: (...) -> None
        self.loc = loc
        self.name = name
        self.fields = fields
        self.directives = directives

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, InputObjectTypeDefinition)
            and
            # self.loc == other.loc and
            self.name == other.name
            and self.fields == other.fields
            and self.directives == other.directives
        )

    def __repr__(self):
        # type: () -> str
        return (
            "InputObjectTypeDefinition("
            "name={self.name!r}"
            ", fields={self.fields!r}"
            ", directives={self.directives!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> InputObjectTypeDefinition
        return type(self)(self.name, self.fields, self.loc, self.directives)

    def __hash__(self):
        # type: () -> int
        return id(self)


class TypeExtensionDefinition(TypeSystemDefinition):
    __slots__ = ("loc", "definition")
    _fields = ("definition",)

    def __init__(self, definition, loc=None):
        # type: (ObjectTypeDefinition, Optional[Loc]) -> None
        self.loc = loc
        self.definition = definition

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, TypeExtensionDefinition)
            and
            # self.loc == other.loc and
            self.definition == other.definition
        )

    def __repr__(self):
        # type: () -> str
        return ("TypeExtensionDefinition(" "definition={self.definition!r}" ")").format(
            self=self
        )

    def __copy__(self):
        # type: () -> TypeExtensionDefinition
        return type(self)(self.definition, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)


class DirectiveDefinition(TypeSystemDefinition):
    __slots__ = ("loc", "name", "arguments", "locations")
    _fields = ("name", "locations")

    def __init__(
        self,
        name,  # type: Name
        locations,  # type: List[Name]
        arguments=None,  # type: Optional[List[InputValueDefinition]]
        loc=None,  # type: Optional[Loc]
    ):
        # type: (...) -> None
        self.name = name
        self.locations = locations
        self.loc = loc
        self.arguments = arguments

    def __eq__(self, other):
        # type: (Any) -> bool
        return self is other or (
            isinstance(other, DirectiveDefinition)
            and self.name == other.name
            and self.locations == other.locations
            and
            # self.loc == other.loc and
            self.arguments == other.arguments
        )

    def __repr__(self):
        # type: () -> str
        return (
            "DirectiveDefinition("
            "name={self.name!r}, "
            "locations={self.locations!r}"
            ")"
        ).format(self=self)

    def __copy__(self):
        # type: () -> DirectiveDefinition
        return type(self)(self.name, self.locations, self.arguments, self.loc)

    def __hash__(self):
        # type: () -> int
        return id(self)
