from _typeshed import ReadableBuffer
from collections.abc import Mapping
from typing import Generic, Literal, TypeAlias, TypeVar, overload
from typing_extensions import Self
from xml.sax import _Source, _SupportsReadClose
from xml.sax.handler import _ContentHandlerProtocol, _DTDHandlerProtocol, _EntityResolverProtocol, _ErrorHandlerProtocol

class XMLReader:
    def parse(self, source: InputSource | _Source) -> None: ...
    def getContentHandler(self) -> _ContentHandlerProtocol: ...
    def setContentHandler(self, handler: _ContentHandlerProtocol) -> None: ...
    def getDTDHandler(self) -> _DTDHandlerProtocol: ...
    def setDTDHandler(self, handler: _DTDHandlerProtocol) -> None: ...
    def getEntityResolver(self) -> _EntityResolverProtocol: ...
    def setEntityResolver(self, resolver: _EntityResolverProtocol) -> None: ...
    def getErrorHandler(self) -> _ErrorHandlerProtocol: ...
    def setErrorHandler(self, handler: _ErrorHandlerProtocol) -> None: ...
    def setLocale(self, locale: str) -> None: ...
    def getFeature(self, name: str) -> Literal[0, 1] | bool: ...
    def setFeature(self, name: str, state: Literal[0, 1] | bool) -> None: ...
    def getProperty(self, name: str) -> object: ...
    def setProperty(self, name: str, value: object) -> None: ...

class IncrementalParser(XMLReader):
    def __init__(self, bufsize: int = 65536) -> None: ...
    def parse(self, source: InputSource | _Source) -> None: ...
    def feed(self, data: str | ReadableBuffer) -> None: ...
    def prepareParser(self, source: InputSource) -> None: ...
    def close(self) -> None: ...
    def reset(self) -> None: ...

class Locator:
    def getColumnNumber(self) -> int | None: ...
    def getLineNumber(self) -> int | None: ...
    def getPublicId(self) -> str | None: ...
    def getSystemId(self) -> str | None: ...

class InputSource:
    def __init__(self, system_id: str | None = None) -> None: ...
    def setPublicId(self, public_id: str | None) -> None: ...
    def getPublicId(self) -> str | None: ...
    def setSystemId(self, system_id: str | None) -> None: ...
    def getSystemId(self) -> str | None: ...
    def setEncoding(self, encoding: str | None) -> None: ...
    def getEncoding(self) -> str | None: ...
    def setByteStream(self, bytefile: _SupportsReadClose[bytes] | None) -> None: ...
    def getByteStream(self) -> _SupportsReadClose[bytes] | None: ...
    def setCharacterStream(self, charfile: _SupportsReadClose[str] | None) -> None: ...
    def getCharacterStream(self) -> _SupportsReadClose[str] | None: ...

_AttrKey = TypeVar("_AttrKey", default=str)

class AttributesImpl(Generic[_AttrKey]):
    def __init__(self, attrs: Mapping[_AttrKey, str]) -> None: ...
    def getLength(self) -> int: ...
    def getType(self, name: str) -> str: ...
    def getValue(self, name: _AttrKey) -> str: ...
    def getValueByQName(self, name: str) -> str: ...
    def getNameByQName(self, name: str) -> _AttrKey: ...
    def getQNameByName(self, name: _AttrKey) -> str: ...
    def getNames(self) -> list[_AttrKey]: ...
    def getQNames(self) -> list[str]: ...
    def __len__(self) -> int: ...
    def __getitem__(self, name: _AttrKey) -> str: ...
    def keys(self) -> list[_AttrKey]: ...
    def __contains__(self, name: _AttrKey) -> bool: ...

    @overload
    def get(self, name: _AttrKey, alternative: None = None) -> str | None: ...
    @overload
    def get(self, name: _AttrKey, alternative: str) -> str: ...

    def copy(self) -> Self: ...
    def items(self) -> list[tuple[_AttrKey, str]]: ...
    def values(self) -> list[str]: ...

_NSName: TypeAlias = tuple[str | None, str]

class AttributesNSImpl(AttributesImpl[_NSName]):
    def __init__(self, attrs: Mapping[_NSName, str], qnames: Mapping[_NSName, str]) -> None: ...
    def getValue(self, name: _NSName) -> str: ...
    def getNameByQName(self, name: str) -> _NSName: ...
    def getQNameByName(self, name: _NSName) -> str: ...
    def getNames(self) -> list[_NSName]: ...
    def __getitem__(self, name: _NSName) -> str: ...
    def keys(self) -> list[_NSName]: ...
    def __contains__(self, name: _NSName) -> bool: ...

    @overload
    def get(self, name: _NSName, alternative: None = None) -> str | None: ...
    @overload
    def get(self, name: _NSName, alternative: str) -> str: ...

    def items(self) -> list[tuple[_NSName, str]]: ...
