import typing, abc
from System import Guid, Array_1
from System.Reflection import FieldAttributes, ParameterAttributes

class ISymbolBinder(typing.Protocol):
    @abc.abstractmethod
    def GetReader(self, importer: int, filename: str, searchPath: str) -> ISymbolReader: ...


class ISymbolBinder1(typing.Protocol):
    @abc.abstractmethod
    def GetReader(self, importer: int, filename: str, searchPath: str) -> ISymbolReader: ...


class ISymbolDocument(typing.Protocol):
    @property
    def CheckSumAlgorithmId(self) -> Guid: ...
    @property
    def DocumentType(self) -> Guid: ...
    @property
    def HasEmbeddedSource(self) -> bool: ...
    @property
    def Language(self) -> Guid: ...
    @property
    def LanguageVendor(self) -> Guid: ...
    @property
    def SourceLength(self) -> int: ...
    @property
    def URL(self) -> str: ...
    @abc.abstractmethod
    def FindClosestLine(self, line: int) -> int: ...
    @abc.abstractmethod
    def GetCheckSum(self) -> Array_1[int]: ...
    @abc.abstractmethod
    def GetSourceRange(self, startLine: int, startColumn: int, endLine: int, endColumn: int) -> Array_1[int]: ...


class ISymbolDocumentWriter(typing.Protocol):
    @abc.abstractmethod
    def SetCheckSum(self, algorithmId: Guid, checkSum: Array_1[int]) -> None: ...
    @abc.abstractmethod
    def SetSource(self, source: Array_1[int]) -> None: ...


class ISymbolMethod(typing.Protocol):
    @property
    def RootScope(self) -> ISymbolScope: ...
    @property
    def SequencePointCount(self) -> int: ...
    @property
    def Token(self) -> SymbolToken: ...
    @abc.abstractmethod
    def GetNamespace(self) -> ISymbolNamespace: ...
    @abc.abstractmethod
    def GetOffset(self, document: ISymbolDocument, line: int, column: int) -> int: ...
    @abc.abstractmethod
    def GetParameters(self) -> Array_1[ISymbolVariable]: ...
    @abc.abstractmethod
    def GetRanges(self, document: ISymbolDocument, line: int, column: int) -> Array_1[int]: ...
    @abc.abstractmethod
    def GetScope(self, offset: int) -> ISymbolScope: ...
    @abc.abstractmethod
    def GetSequencePoints(self, offsets: Array_1[int], documents: Array_1[ISymbolDocument], lines: Array_1[int], columns: Array_1[int], endLines: Array_1[int], endColumns: Array_1[int]) -> None: ...
    @abc.abstractmethod
    def GetSourceStartEnd(self, docs: Array_1[ISymbolDocument], lines: Array_1[int], columns: Array_1[int]) -> bool: ...


class ISymbolNamespace(typing.Protocol):
    @property
    def Name(self) -> str: ...
    @abc.abstractmethod
    def GetNamespaces(self) -> Array_1[ISymbolNamespace]: ...
    @abc.abstractmethod
    def GetVariables(self) -> Array_1[ISymbolVariable]: ...


class ISymbolReader(typing.Protocol):
    @property
    def UserEntryPoint(self) -> SymbolToken: ...
    @abc.abstractmethod
    def GetDocument(self, url: str, language: Guid, languageVendor: Guid, documentType: Guid) -> ISymbolDocument: ...
    @abc.abstractmethod
    def GetDocuments(self) -> Array_1[ISymbolDocument]: ...
    @abc.abstractmethod
    def GetGlobalVariables(self) -> Array_1[ISymbolVariable]: ...
    @abc.abstractmethod
    def GetMethodFromDocumentPosition(self, document: ISymbolDocument, line: int, column: int) -> ISymbolMethod: ...
    @abc.abstractmethod
    def GetNamespaces(self) -> Array_1[ISymbolNamespace]: ...
    @abc.abstractmethod
    def GetSymAttribute(self, parent: SymbolToken, name: str) -> Array_1[int]: ...
    @abc.abstractmethod
    def GetVariables(self, parent: SymbolToken) -> Array_1[ISymbolVariable]: ...
    # Skipped GetMethod due to it being static, abstract and generic.

    GetMethod : GetMethod_MethodGroup
    class GetMethod_MethodGroup:
        @typing.overload
        def __call__(self, method: SymbolToken) -> ISymbolMethod:...
        @typing.overload
        def __call__(self, method: SymbolToken, version: int) -> ISymbolMethod:...



class ISymbolScope(typing.Protocol):
    @property
    def EndOffset(self) -> int: ...
    @property
    def Method(self) -> ISymbolMethod: ...
    @property
    def Parent(self) -> ISymbolScope: ...
    @property
    def StartOffset(self) -> int: ...
    @abc.abstractmethod
    def GetChildren(self) -> Array_1[ISymbolScope]: ...
    @abc.abstractmethod
    def GetLocals(self) -> Array_1[ISymbolVariable]: ...
    @abc.abstractmethod
    def GetNamespaces(self) -> Array_1[ISymbolNamespace]: ...


class ISymbolVariable(typing.Protocol):
    @property
    def AddressField1(self) -> int: ...
    @property
    def AddressField2(self) -> int: ...
    @property
    def AddressField3(self) -> int: ...
    @property
    def AddressKind(self) -> SymAddressKind: ...
    @property
    def Attributes(self) -> typing.Any: ...
    @property
    def EndOffset(self) -> int: ...
    @property
    def Name(self) -> str: ...
    @property
    def StartOffset(self) -> int: ...
    @abc.abstractmethod
    def GetSignature(self) -> Array_1[int]: ...


class ISymbolWriter(typing.Protocol):
    @abc.abstractmethod
    def Close(self) -> None: ...
    @abc.abstractmethod
    def CloseMethod(self) -> None: ...
    @abc.abstractmethod
    def CloseNamespace(self) -> None: ...
    @abc.abstractmethod
    def CloseScope(self, endOffset: int) -> None: ...
    @abc.abstractmethod
    def DefineDocument(self, url: str, language: Guid, languageVendor: Guid, documentType: Guid) -> ISymbolDocumentWriter: ...
    @abc.abstractmethod
    def DefineField(self, parent: SymbolToken, name: str, attributes: FieldAttributes, signature: Array_1[int], addrKind: SymAddressKind, addr1: int, addr2: int, addr3: int) -> None: ...
    @abc.abstractmethod
    def DefineGlobalVariable(self, name: str, attributes: FieldAttributes, signature: Array_1[int], addrKind: SymAddressKind, addr1: int, addr2: int, addr3: int) -> None: ...
    @abc.abstractmethod
    def DefineLocalVariable(self, name: str, attributes: FieldAttributes, signature: Array_1[int], addrKind: SymAddressKind, addr1: int, addr2: int, addr3: int, startOffset: int, endOffset: int) -> None: ...
    @abc.abstractmethod
    def DefineParameter(self, name: str, attributes: ParameterAttributes, sequence: int, addrKind: SymAddressKind, addr1: int, addr2: int, addr3: int) -> None: ...
    @abc.abstractmethod
    def DefineSequencePoints(self, document: ISymbolDocumentWriter, offsets: Array_1[int], lines: Array_1[int], columns: Array_1[int], endLines: Array_1[int], endColumns: Array_1[int]) -> None: ...
    @abc.abstractmethod
    def Initialize(self, emitter: int, filename: str, fFullBuild: bool) -> None: ...
    @abc.abstractmethod
    def OpenMethod(self, method: SymbolToken) -> None: ...
    @abc.abstractmethod
    def OpenNamespace(self, name: str) -> None: ...
    @abc.abstractmethod
    def OpenScope(self, startOffset: int) -> int: ...
    @abc.abstractmethod
    def SetMethodSourceRange(self, startDoc: ISymbolDocumentWriter, startLine: int, startColumn: int, endDoc: ISymbolDocumentWriter, endLine: int, endColumn: int) -> None: ...
    @abc.abstractmethod
    def SetScopeRange(self, scopeID: int, startOffset: int, endOffset: int) -> None: ...
    @abc.abstractmethod
    def SetSymAttribute(self, parent: SymbolToken, name: str, data: Array_1[int]) -> None: ...
    @abc.abstractmethod
    def SetUnderlyingWriter(self, underlyingWriter: int) -> None: ...
    @abc.abstractmethod
    def SetUserEntryPoint(self, entryMethod: SymbolToken) -> None: ...
    @abc.abstractmethod
    def UsingNamespace(self, fullName: str) -> None: ...


class SymAddressKind(typing.SupportsInt):
    @typing.overload
    def __init__(self, value : int) -> None: ...
    @typing.overload
    def __init__(self, value : int, force_if_true: bool) -> None: ...
    def __int__(self) -> int: ...
    
    # Values:
    ILOffset : SymAddressKind # 1
    NativeRVA : SymAddressKind # 2
    NativeRegister : SymAddressKind # 3
    NativeRegisterRelative : SymAddressKind # 4
    NativeOffset : SymAddressKind # 5
    NativeRegisterRegister : SymAddressKind # 6
    NativeRegisterStack : SymAddressKind # 7
    NativeStackRegister : SymAddressKind # 8
    BitField : SymAddressKind # 9
    NativeSectionOffset : SymAddressKind # 10


class SymbolToken:
    def __init__(self, val: int) -> None: ...
    def GetHashCode(self) -> int: ...
    def GetToken(self) -> int: ...
    def __eq__(self, a: SymbolToken, b: SymbolToken) -> bool: ...
    def __ne__(self, a: SymbolToken, b: SymbolToken) -> bool: ...
    # Skipped Equals due to it being static, abstract and generic.

    Equals : Equals_MethodGroup
    class Equals_MethodGroup:
        @typing.overload
        def __call__(self, obj: SymbolToken) -> bool:...
        @typing.overload
        def __call__(self, obj: typing.Any) -> bool:...



class SymDocumentType:
    def __init__(self) -> None: ...
    Text : Guid


class SymLanguageType:
    def __init__(self) -> None: ...
    Basic : Guid
    C : Guid
    Cobol : Guid
    CPlusPlus : Guid
    CSharp : Guid
    ILAssembly : Guid
    Java : Guid
    JScript : Guid
    MCPlusPlus : Guid
    Pascal : Guid
    SMC : Guid


class SymLanguageVendor:
    def __init__(self) -> None: ...
    Microsoft : Guid

