from enum import IntEnum
from typing import Any, Dict, List, NewType, Optional, Tuple, Union

from wake.utils import StrEnum

from .lsp_data_model import LspModel

DocumentUri = NewType("URI", str)
URI = NewType("URI", str)
ChangeAnnotationIdentifier = NewType("ChangeAnnotationIdentifier", str)
ProgressToken = Union[int, str]
TraceValue = NewType("Trace", str)  # NewType(Union["off","message","verbose"], str)


class RegularExpressionsClientCapabilities(LspModel):
    engine: str
    """
    The engine's name.
    """
    version: Optional[str] = None
    """
    The engine's version.
    """


class Position(LspModel):
    line: int
    """
    Position in a document (zero-based).
    """
    character: int
    """
    Character offset on a line in a document (zero-based).between the `character` and `character + 1`.
    """

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return (self.line, self.character) == (other.line, other.character)
        return NotImplemented

    def __hash__(self):
        return hash((self.line, self.character))


class Range(LspModel):
    start: Position
    """
    The range's start position.
    """
    end: Position
    """
    The range's end position.
    """

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return (self.start, self.end) == (other.start, other.end)
        return NotImplemented

    def __hash__(self):
        return hash((self.start, self.end))


class Location(LspModel):
    """
    Represents a location inside a resource, such as a line inside a text file.
    """

    uri: DocumentUri
    range: Range

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return (self.uri, self.range) == (other.uri, other.range)
        return NotImplemented

    def __hash__(self):
        return hash((self.uri, self.range))


class LocationLink(LspModel):
    origin_selection_range: Optional[Range] = None
    """
    Span of the origin of this link.
    Used as the underlined span for mouse interaction.
    Defaults to the word range at the mouse position.
    """
    target_uri: str
    """
     The target resource identifier of this link.
    """
    target_range: Range
    """
    The full target range of this link.
    """
    target_selection_range: Range
    """
    The range that should be selected and revealed when this link is being followed,
    e.g the name of a function. Must be contained by the the `target_Range`.
    """


class DiagnosticSeverity(IntEnum):
    ERROR = 1
    WARNING = 2
    INFORMATION = 3
    HINT = 4


class DiagnosticTag(IntEnum):
    UNNECESSARY = 1
    """
    Unused or unnecessary code
    """
    DEPRECATED = 2
    """
    Deprecated or obsolete code
    """


class DiagnosticRelatedInformation(LspModel):
    location: Location
    """
    The location of this related diagnostic information.
    """
    message: str
    """
    The message of this related diagnostic information.
    """

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return (self.location, self.message) == (other.location, other.message)
        return NotImplemented

    def __hash__(self):
        return hash((self.location, self.message))


class CodeDescription(LspModel):
    href: URI
    """
    URI to open with more info.
    """

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.href == other.href
        return NotImplemented

    def __hash__(self):
        return hash(self.href)


class Diagnostic(LspModel):
    range: Range
    """
    The range at which the message applies.
    """
    severity: Optional[DiagnosticSeverity] = None
    """
    The diagnostic's severity.
    """
    code: Optional[Union[int, str]] = None
    """
    The diagnostic's code.
    """
    code_description: Optional[CodeDescription] = None
    """
    An URI to open with more information about the diagnostic error.
    """
    source: Optional[str] = None
    """
    A human-readable string describing the source of this diagnostic
    """
    message: str
    """
    The diagnostic's message.
    """
    tags: Optional[List[DiagnosticTag]] = None
    """
    Additional metadata about the diagnostic.
    """
    related_information: Optional[List[DiagnosticRelatedInformation]] = None
    """
    An array of related diagnostic information,
    e.g. when symbol-names within a scope collide all definitions can be marked via this property.
    """
    data: Optional[Any] = None
    """
    A data entry field that is preserved between
    a `textDocument/publishDiagnostics` notification and `textDocument/codeAction` request.
    """

    def __members(self) -> Tuple:
        return (
            self.range,
            self.severity,
            self.code,
            self.code_description,
            self.source,
            self.message,
            frozenset(self.tags) if self.tags is not None else None,
            frozenset(self.related_information)
            if self.related_information is not None
            else None,
            self.data,
        )

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__members() == other.__members()
        return NotImplemented

    def __hash__(self):
        return hash(self.__members())


class Command(LspModel):
    title: str
    """
    Title of the command, like `save`.
    """
    command: str
    """
    The identifier of the actual command handler.
    """
    arguments: Optional[List[Any]] = None
    """
    Arguments that the command handler should be invoked with.
    """


class TextEdit(LspModel):
    range: Range
    """
    The range of the text document to be manipulated.
    To insert text into a document create a range where start === end.
    """
    new_text: str
    """
    The text to be inserted. For delete operations use an empty string.
    """


class ChangeAnnotation(LspModel):
    label: str
    """
    A human-readable string describing the actual change.
    """
    needs_confirmation: Optional[bool] = None
    """
    A flag which indicates that user confirmation is needed before applying the change.
    """
    description: Optional[str] = None
    """
    A human-readable string which is rendered less prominent in the user interface.
    """


class AnnotatedTextEdit(TextEdit):
    annotation_id: ChangeAnnotationIdentifier
    """
    The actual annotation identifier.
    """


class TextDocumentIdentifier(LspModel):
    uri: DocumentUri
    """
    The text document's URI.
    """


class VersionedTextDocumentIdentifier(TextDocumentIdentifier):
    version: int
    """
    The version number of this document.
    The version number of a document will increase after each change,
    including undo/redo. The number doesn't need to be consecutive.
    """


class OptionalVersionedTextDocumentIdentifier(TextDocumentIdentifier):
    version: Optional[Union[int, None]] = None
    """
    The version number of this document. If an optional versioned text document
    identifier is sent from the server to the client and the file is not
    open in the editor (the server has not received an open notification
    before) the server can send `null` to indicate that the version is
    known and the content on disk is the master (as specified with document
    content ownership).
    The version number of a document will increase after each change,
    including undo/redo. The number doesn't need to be consecutive.
    """


class TextDocumentEdit(LspModel):
    text_document: OptionalVersionedTextDocumentIdentifier = None
    """
    The text document to change.
    """
    edits: List[Union[TextEdit, AnnotatedTextEdit]]
    """
    The edits to be applied.
    """


class CreateFileOptions(LspModel):
    """
    Options to create a file.
    """

    overwrite: Optional[bool] = None
    """
    Overwrite existing file. Overwrite wins over `ignoreIfExists`
    """
    ignore_if_exists: Optional[bool] = None
    """
    Ignore if exists.
    """


class CreateFile(LspModel):
    """
    Create file operation.
    """

    kind: str = "create"
    """
    A create.
    """
    uri: DocumentUri
    """
    The resource to create.
    """
    options: Optional[CreateFileOptions] = None
    """
    Additional options.
    """
    annotation_id: Optional[ChangeAnnotationIdentifier] = None
    """
    An optional annotation identifier describing the operation.
    """


class RenameFileOptions(LspModel):
    """
    Rename file options.
    """

    overwrite: Optional[bool] = None
    """
    Overwrite target if existing. Overwrite wins over `ignoreIfExists`.
    """
    ignore_if_exists: Optional[bool] = None
    """
    Ignores if target exists.
    """


class RenameFile(LspModel):
    """
    Rename file operation.
    """

    kind: str = "rename"
    """
    A rename.
    """
    old_uri: DocumentUri
    """
    The old (existing) location.
    """
    new_uri: DocumentUri
    """
    The new location.
    """
    options: Optional[RenameFileOptions] = None
    """
    Rename options.
    """
    annotation_id: Optional[ChangeAnnotationIdentifier] = None
    """
    An optional annotation identifier describing the operation.
    """


class DeleteFileOptions(LspModel):
    """
    Delete file options.
    """

    recursive: Optional[bool] = None
    """
    Delete the content recursively if a folder denoted.
    """
    ignore_if_not_exists: Optional[bool] = None
    """
    Ignore the operation if the file does not exists.
    """


class DeleteFile(LspModel):
    """
    Delete file operation
    """

    kind: str = "delete"
    """
    A delete.
    """
    uri: DocumentUri
    """
    The file to delete
    """
    options: Optional[RenameFileOptions] = None
    """
    Delete options.
    """
    annotation_id: Optional[ChangeAnnotationIdentifier] = None
    """
    An optional annotation identifier describing the operation.
    """


class WorkspaceEdit(LspModel):
    changes: Optional[Dict[DocumentUri, List[TextEdit]]] = None
    """
    Holds changes to existing resource.
    """
    document_changes: Optional[
        List[Union[TextDocumentEdit, CreateFile, RenameFile, DeleteFile]]
    ] = None
    """
    Depending on the client capability
    `workspace.workspaceEdit.resourceOperations` document changes are either
    an array of `TextDocumentEdit`s to express changes to n different text
    documents where each text document edit applies to a specific version of
    a text document. Or it can contain above `TextDocumentEdit`s mixed with
    create, rename and delete file / folder operations.

    Whether a client supports versioned document edits is expressed via
    `workspace.workspaceEdit.documentChanges` client capability.

    If a client neither supports `documentChanges` nor
    `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
    using the `changes` property are supported.
    """
    change_annotations: Optional[Dict[str, ChangeAnnotation]] = None
    """
    A map of change annotations that can be referenced in
    `AnnotatedTextEdit`s or create, rename, delete file / folder
    operations.

    Whether clients honor this property depends on the client capability
    `workspace.changeAnnotationSupport`.

    @since 3.16.0
    """


class ResourceOperationKind(StrEnum):
    CREATE = "create"
    RENAME = "rename"
    DELETE = "delete"


class FailureHandlingKind(StrEnum):
    ABORT = "abort"
    TRANSACTIONAL = "transactional"
    TEXT_ONLY_TRANSACTIONAL = "textOnlyTransactional"
    UNDO = "undo"


class ChangeAnnotationsSupport(LspModel):
    groups_on_label: Optional[bool] = None


class WorkspaceEditClientCapabilities(LspModel):
    document_changes: Optional[bool] = None
    """
    The client supports versioned document changes in `WorkspaceEdit`s
    """
    resource_operations: Optional[List[ResourceOperationKind]] = None
    """
    The resource operations the client supports.
    Clients should at least support 'create', 'rename' and 'delete' files and folders.
    """
    failure_handling: Optional[FailureHandlingKind] = None
    """
    The failure handling strategy of a client if applying the workspace edit fails.
    """
    normalizes_line_endings: Optional[bool] = None
    """
    Whether the client normalizes line endings to the client specific setting.
    If set to `true` the client will normalize line ending characters
    in a workspace edit to the client specific new line character(s).
    """
    # ?
    change_annotation_support: Optional[ChangeAnnotationsSupport] = None
    """
    Whether the client in general supports change annotations on text edits,
    create file, rename file and delete file changes.
    """


class TextDocumentItem(LspModel):
    uri: DocumentUri
    """
    The text document's URI.
    """
    language_id: str
    """
    The text document's language identifier.
    """
    version: int
    """
    The version number of this document (it will increase after each change, including undo/redo).
    """
    text: str
    """
    The content of the opened text document.
    """


class TextDocumentPositionParams(LspModel):
    text_document: TextDocumentIdentifier
    """
    The text document.
    """
    position: Position
    """
    The position inside the text document.z
    """


class DocumentFilter(LspModel):
    language: Optional[str] = None
    """
    A language ID, like 'typescript'.
    """
    scheme: Optional[str] = None
    """
     A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
    """
    pattern: Optional[str] = None
    """
    Glob patterns can have the following syntax:
    * `*` to match one or more characters in a path segment
    * `?` to match on one character in a path segment
    * `**` to match any number of path segments, including none
    * `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}`
        matches all TypeScript and JavaScript files)
    * `[]` to declare a range of characters to match in a path segment
        (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
    * `[!...]` to negate a range of characters to match in a path segment
        (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but
        not `example.0`)
    """


class StaticRegistrationOptions(LspModel):
    """
    Static registration options to be returned in the initialize request.
    """

    id: Optional[str] = None
    """
    The id used to register the request.
    The id can be used to deregister the request again. See also Registration#id.
    """


class TextDocumentRegistrationOptions(LspModel):
    """
    General text document registration options.
    """

    document_selector: Optional[List[DocumentFilter]] = None
    """
    A document selector to identify the scope of the registration.
    If set to null the document selector provided on the client side will be used.
    """


class MarkupKind(StrEnum):
    PLAIN_TEXT = "plaintext"
    MARKDOWN = "markdown"


class MarkupContent(LspModel):
    kind: MarkupKind
    """
    The type of the Markup.
    """
    value: str
    """
    The content itself.
    """


class MarkupClientCapabilities(LspModel):
    parser: MarkupKind
    """
    The name of the parser.
    """
    version: Optional[str] = None
    """
    The version of the parser.
    """
    allowed_tags: Optional[List[str]] = None
    """
    A list of HTML tags that the client allows / supports in Markdown.

    Known markdown parsers used by clients right now are:
    -------------------------------------------------------------
    Parser	            Version	    Documentation
    -------------------------------------------------------------
    marked	            1.1.0	    Marked Documentation
    Python-Markdown	    3.2.2	    Python-Markdown Documentation
    -------------------------------------------------------------
    """


class WorkDoneProgressBegin(LspModel):
    kind: str = "begin"
    title: str
    """
    Mandatory title of the progress operation. Used to briefly inform about
    the kind of operation being performed.

    Examples: "Indexing" or "Linking dependencies".
    """
    cancellable: Optional[bool] = None
    """
    Controls if a cancel button should show to allow the user to cancel the
    long running operation. Clients that don't support cancellation are
    allowed to ignore the setting.
    """
    message: Optional[str] = None
    """
    Optional, more detailed associated progress message. Contains
    complementary information to the `title`.

    Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
    If unset, the previous progress message (if any) is still valid.
    """
    percentage: Optional[int] = None
    """
    Optional progress percentage to display (value 100 is considered 100%).
    If not provided infinite progress is assumed and clients are allowed
    to ignore the `percentage` value in subsequent in report notifications.
    """


class WorkDoneProgressReport(LspModel):
    kind: str = "report"
    cancellable: Optional[bool] = None
    """
    Controls if a cancel button should show to allow the user to cancel the
    long running operation. Clients that don't support cancellation are
    allowed to ignore the setting.
    """
    message: Optional[str] = None
    """
    Optional, more detailed associated progress message. Contains
    complementary information to the `title`.
    """
    percentage: Optional[int] = None
    """
    Optional progress percentage to display (value 100 is considered 100%).
    If not provided infinite progress is assumed and clients are allowed
    to ignore the `percentage` value in subsequent in report notifications.
    """


class WorkDoneProgressEnd(LspModel):
    kind: str = "end"
    message: Optional[str] = None
    """
    Optional, a final message indicating to for example indicate the outcome
    of the operation.
    """


class WorkDoneProgressParams(LspModel):
    work_done_token: Optional[ProgressToken] = None
    """
    An optional token that a server can use to report work done progress.
    """


class WorkDoneProgressOptions(LspModel):
    work_done_progress: Optional[bool] = None


class PartialResultParams(LspModel):
    partial_result_token: Optional[ProgressToken] = None
    """
    An optional token that a server can use to report partial results (e.g.streaming)
    to the client.
    """


# ##################### Lifecycle Message #####################


class ClientCapabilitiesWorkspaceFileOperation(LspModel):
    dynamic_registration: Optional[bool] = None
    did_create: Optional[bool] = None
    will_create: Optional[bool] = None
    did_rename: Optional[bool] = None
    will_rename: Optional[bool] = None
    did_delete: Optional[bool] = None
    will_delete: Optional[bool] = None


class InitializeErrorCodes(IntEnum):
    unknown_protocol_version = 1


class InitializeError(LspModel):
    retry: bool


class InitializedParams(LspModel):
    pass


class MessageType(IntEnum):
    ERROR = 1
    WARNING = 2
    INFO = 3
    LOG = 4


class ShowMessageParams(LspModel):
    type: MessageType
    message: str


class ShowMessageRequestClientCapabilitiesMessageActionItem(LspModel):
    additional_properties_support: Optional[bool] = None


class ShowMessageRequestClientCapabilities(LspModel):
    message_action_item: Optional[
        ShowMessageRequestClientCapabilitiesMessageActionItem
    ] = None


class MessageActionItem(LspModel):
    title: str


class ShowMessageRequestParams(LspModel):
    type: MessageType
    message: str
    actions: Optional[List[MessageActionItem]] = None


class ShowDocumentClientCapabilities(LspModel):
    support: bool


class ShowDocumentParams(LspModel):
    uri: URI
    external: Optional[bool] = None
    take_focus: Optional[bool] = None
    selection: Optional[Range] = None


class ShowDocumentResult(LspModel):
    success: bool
    """
    A boolean indicating if the show was successful.
    """


class LogMessageParams(LspModel):
    type: MessageType
    """
    The message type
    """
    message: str
    """
    The actual message
    """


class PublishDiagnosticsParams(LspModel):
    uri: DocumentUri
    """
    The URI for which diagnostic information is reported.
    """
    version: Optional[int] = None
    """
    Optional the version number of the document the diagnostics are published for.

    @since 3.15.0
    """
    diagnostics: List[Diagnostic]
    """
    An array of diagnostic information items.
    """


class WorkDoneProgressCreateParams(LspModel):
    token: ProgressToken
    """
    The token to be used to report progress.
    """


class WorkDoneProgressCancelParams(LspModel):
    token: ProgressToken


class Registration(LspModel):
    id: str
    """
    The id used to register the request. The id can be used to deregister
    the request again.
    """
    method: str
    """
    The method / capability to register for.
    """
    register_options: Optional[Any] = None
    """
    Options necessary for the registration.
    """


class RegistrationParams(LspModel):
    registrations: List[Registration]


class Unregistration(LspModel):
    id: str
    """
    The id used to unregister the request or notification. Usually an id
    provided during the register request.
    """
    method: str
    """
    The method / capability to unregister for.
    """


class UnregistrationParams(LspModel):
    unregistrations: List[Unregistration]


class SetTraceParams(LspModel):
    value: TraceValue
    """
    The new value that should be assigned to the trace setting.
    """


class LogTraceParams(LspModel):
    message: str
    """
    The message to be logged.
    """
    verbose: Optional[str] = None
    """
    Additional information that can be computed if the `trace` configuration
    is set to `'verbose'`
    """


class ProgressParams(LspModel):
    token: ProgressToken
    """
    The progress token provided by the client or server.
    """
    value: Any
    """
    The progress data.
    """


class SymbolKind(IntEnum):
    FILE = 1
    MODULE = 2
    NAMESPACE = 3
    PACKAGE = 4
    CLASS = 5
    METHOD = 6
    PROPERTY = 7
    FIELD = 8
    CONSTRUCTOR = 9
    ENUM = 10
    INTERFACE = 11
    FUNCTION = 12
    VARIABLE = 13
    CONSTANT = 14
    STRING = 15
    NUMBER = 16
    BOOLEAN = 17
    ARRAY = 18
    OBJECT = 19
    KEY = 20
    NULL = 21
    ENUMMEMBER = 22
    STRUCT = 23
    EVENT = 24
    OPERATOR = 25
    TYPEPARAMETER = 26


class SymbolTag(IntEnum):
    DEPRECATED = 1


class DocumentSymbol(LspModel):
    name: str
    detail: Optional[str] = None
    kind: SymbolKind
    tags: Optional[List[SymbolTag]] = None
    deprecated: Optional[bool] = None
    range: Range
    selection_range: Range
    children: Optional[List["DocumentSymbol"]] = None


class SymbolInformation(LspModel):
    name: str
    kind: SymbolKind
    tags: Optional[List[SymbolTag]] = None
    deprecated: Optional[bool] = None
    location: Location
    container_name: Optional[str] = None


class WorkspaceSymbolClientCapabilitiesSymbolKind(LspModel):
    value_set: Optional[List[SymbolKind]] = None


class WorkspaceSymbolClientCapabilitiesTagSupport(LspModel):
    value_set: List[SymbolTag]


class WorkspaceSymbolClientCapabilitiesResolveSupport(LspModel):
    properties: List[str]


class WorkspaceSymbolClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None
    symbol_kind: Optional[WorkspaceSymbolClientCapabilitiesSymbolKind] = None
    tag_support: Optional[WorkspaceSymbolClientCapabilitiesTagSupport] = None
    resolve_support: Optional[WorkspaceSymbolClientCapabilitiesResolveSupport] = None


class WorkspaceSymbolOptions(WorkDoneProgressOptions):
    resolve_provider: Optional[bool] = None


class WorkspaceSymbolRegistrationOptions(WorkspaceSymbolOptions):
    pass


class WorkspaceSymbolParams(WorkDoneProgressParams, PartialResultParams):
    query: str


class WorkspaceSymbolUriLocation(LspModel):
    uri: DocumentUri


class WorkspaceSymbol(LspModel):
    name: str
    kind: SymbolKind
    tags: Optional[List[SymbolTag]] = None
    location: Union[Location, WorkspaceSymbolUriLocation]
    container_name: Optional[str] = None


class ConfigurationItem(LspModel):
    scope_uri: Optional[DocumentUri] = None
    section: Optional[str] = None


class ConfigurationParams(LspModel):
    items: List[ConfigurationItem]


class DidChangeConfigurationClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None


class DidChangeConfigurationParams(LspModel):
    settings: Any


class WorkspaceFolder(LspModel):
    uri: DocumentUri
    name: str


class WorkspaceFoldersChangeEvent(LspModel):
    added: List[WorkspaceFolder]
    removed: List[WorkspaceFolder]


class DidChangeWorkspaceFoldersParams(LspModel):
    event: WorkspaceFoldersChangeEvent


class FileCreate(LspModel):
    uri: str


class CreateFilesParams(LspModel):
    files: List[FileCreate]


class FileRename(LspModel):
    old_uri: str
    new_uri: str


class RenameFilesParams(LspModel):
    files: List[FileRename]


class FileDelete(LspModel):
    uri: str


class DeleteFilesParams(LspModel):
    files: List[FileDelete]


class DidChangeWatchedFilesClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None


class RelativePattern(LspModel):
    base_uri: Union[WorkspaceFolder, URI]
    pattern: str


class FileSystemWatcher(LspModel):
    glob_pattern: Union[str, RelativePattern]
    kind: Optional[int] = None


class DidChangeWatchedFilesRegistrationOptions(LspModel):
    watchers: List[FileSystemWatcher]


class WatchKind(IntEnum):
    CREATE = 1
    CHANGE = 2
    DELETE = 4


class FileChangeType(IntEnum):
    CREATED = 1
    CHANGED = 2
    DELETED = 3


class FileEvent(LspModel):
    uri: DocumentUri
    type: FileChangeType


class DidChangeWatchedFilesParams(LspModel):
    changes: List[FileEvent]


class ExecuteCommandClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None


class ExecuteCommandOptions(WorkDoneProgressOptions):
    commands: List[str]


class ExecuteCommandRegistrationOptions(ExecuteCommandOptions):
    pass


class ExecuteCommandParams(WorkDoneProgressParams):
    command: str
    arguments: Optional[List[Any]] = None


class ApplyWorkspaceEditParams(LspModel):
    label: Optional[str] = None
    edit: WorkspaceEdit


class ApplyWorkspaceEditResult(LspModel):
    applied: bool
    failure_reason: Optional[str] = None
    failed_change: Optional[int] = None


class CodeLensWorkspaceClientCapabilities(LspModel):
    refresh_support: Optional[bool] = None


class SemanticTokensClientCapabilitiesRequestsFull(LspModel):
    delta: Optional[bool] = None


class SemanticTokensClientCapabilitiesRequests(LspModel):
    range: Optional[bool] = None
    full: Optional[Union[bool, SemanticTokensClientCapabilitiesRequestsFull]] = None


class TokenFormat(LspModel):
    pass


class SemanticTokensClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None
    requests: Optional[SemanticTokensClientCapabilitiesRequests] = None
    token_types: List[str] = []
    token_modifiers: List[str] = []
    formats: List[TokenFormat] = []
    overlapping_token_support: Optional[bool] = None
    multiline_token_support: Optional[bool] = None
    server_cancel_support: Optional[bool] = None
    augments_syntax_tokens: Optional[bool] = None


class SemanticTokensWorkspaceClientCapabilities(LspModel):
    refresh_support: Optional[bool] = None


class TextDocumentSyncClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None
    will_save: Optional[bool] = None
    will_save_wait_until: Optional[bool] = None
    did_save: Optional[bool] = None


class ClientCapabilitiesWorkspace(LspModel):
    apply_edit: Optional[bool] = None
    workspace_edit: Optional[WorkspaceEditClientCapabilities] = None
    did_change_configuration: Optional[DidChangeConfigurationClientCapabilities] = None
    did_change_watched_files: Optional[DidChangeWatchedFilesClientCapabilities] = None
    symbol: Optional[WorkspaceSymbolClientCapabilities] = None
    execute_command: Optional[ExecuteCommandClientCapabilities] = None
    workspace_folders: Optional[bool] = None
    configuration: Optional[bool] = None
    semantic_tokens: Optional[SemanticTokensWorkspaceClientCapabilities] = None
    code_lens: Optional[CodeLensWorkspaceClientCapabilities] = None
    file_operations: Optional[ClientCapabilitiesWorkspaceFileOperation] = None


class TextDocumentClientCapabilities(LspModel):
    synchronization: Optional[TextDocumentSyncClientCapabilities] = None
    """
    completion: Optional[CompletionClientCapabilities]
    hover: Optional[HoverClientCapabilities]
    signature_help: Optional[SignatureHelpClientCapabilities]
    declaration: Optional[DeclarationClientCapabilities]
    definition: Optional[DefinitionClientCapabilities]
    type_definition: Optional[TypeDefinitionClientCapabilities]
    implementation: Optional[ImplementationClientCapabilities]
    references: Optional[ReferenceClientCapabilities]
    document_highlight: Optional[DocumentHighlightClientCapabilities]
    document_symbol: Optional[DocumentSymbolClientCapabilities]
    code_action: Optional[CodeActionClientCapabilities]
    document_link: Optional[DocumentLinkClientCapabilities]
    color_provider: Optional[DocumentColorClientCapabilities]
    formatting: Optional[DocumentFormattingClientCapabilities]
    range_formatting: Optional[DocumentRangeFormattingClientCapabilities]
    on_type_formatting: Optional[DocumentOnTypeFormattingClientCapabilities]
    rename: Optional[RenameClientCapabilities]
    publish_diagnostic: Optional[PublishDiagnosticsClientCapabilities]
    folding_range: Optional[FoldingRangeClientCapabilities]
    selection_range: Optional[SelectionRangeClientCapabilities]
    linked_editing_range: Optional[LinkedEditingRangeClientCapabilities]
    call_hierarchy: Optional[CallHierarchyClientCapabilities]
    semantic_tokens: Optional[SemanticTokensClientCapabilities]
    moniker: Optional[MonikerClientCapabilities]
    type_hierarchy: Optional[TypeHierarchyClientCapabilities]
    inline_valie: Optional[InlineValueClientCapabilities]
    inlay_hint: Optional[InlayHintClientCapabilities]
    """


class ClientCapabilitiesGeneralStaleRequestSupport(LspModel):
    cancel: bool
    retry_on_content_modified: List[str]


class PositionEncodingKind(StrEnum):
    UTF8 = "utf-8"
    UTF16 = "utf-16"
    UTF32 = "utf-32"


class ClientCapabilitiesGeneral(LspModel):
    stale_request_support: Optional[ClientCapabilitiesGeneralStaleRequestSupport] = None
    regular_expressions: Optional[RegularExpressionsClientCapabilities] = None
    position_encodings: Optional[List[PositionEncodingKind]] = None
    """
    markdown: Optional[MarkdownClientCapabilities]
    """


class ClientCapabilitiesWindow(LspModel):
    work_done_progress: Optional[bool] = None
    show_message: Optional[ShowMessageRequestClientCapabilities] = None
    show_document: Optional[ShowDocumentClientCapabilities] = None


class NotebookDocumentSyncClientCapabilities(LspModel):
    dynamic_registration: Optional[bool] = None
    execution_summary_support: Optional[bool] = None


class NotebookDocumentClientCapabilities(LspModel):
    synchronization: NotebookDocumentSyncClientCapabilities


class ClientCapabilities(LspModel):
    workspace: Optional[ClientCapabilitiesWorkspace] = None
    text_document: Optional[TextDocumentClientCapabilities] = None
    notebook_document: Optional[NotebookDocumentClientCapabilities] = None
    window: Optional[ClientCapabilitiesWindow] = None
    general: Optional[ClientCapabilitiesGeneral] = None
    experimental: Optional[Any] = None


class InitializeParamsClientInfo(LspModel):
    name: str
    version: Optional[str] = None


class InitializeParams(LspModel):
    process_id: Optional[int] = None
    client_info: Optional[InitializeParamsClientInfo] = None
    locale: Optional[str] = None
    root_path: Optional[str] = None
    root_uri: Optional[DocumentUri] = None
    initialization_options: Optional[Any] = None
    capabilities: ClientCapabilities
    trace: Optional[TraceValue] = None
    workspace_folders: Optional[List[WorkspaceFolder]] = None


class TextDocumentContentParams(LspModel):
    uri: DocumentUri


class TextDocumentContentResult(LspModel):
    text: str
