from _typeshed import SupportsItems
from collections.abc import Iterable, Iterator, KeysView, Mapping, Sequence
from datetime import datetime, timedelta, tzinfo
from typing import Any as tAny, TypeAlias

from google.protobuf import struct_pb2
from google.protobuf.descriptor import Descriptor
from google.protobuf.message import Message as _Message

class Any:
    __slots__ = ()
    type_url: str
    value: bytes
    def Pack(self, msg: _Message, type_url_prefix: str = "type.googleapis.com/", deterministic: bool | None = None) -> None: ...
    def Unpack(self, msg: _Message) -> bool: ...
    def TypeName(self) -> str: ...
    def Is(self, descriptor: Descriptor) -> bool: ...

class Timestamp:
    __slots__ = ()
    def ToJsonString(self) -> str: ...
    seconds: int
    nanos: int
    def FromJsonString(self, value: str) -> None: ...
    def GetCurrentTime(self) -> None: ...
    def ToNanoseconds(self) -> int: ...
    def ToMicroseconds(self) -> int: ...
    def ToMilliseconds(self) -> int: ...
    def ToSeconds(self) -> int: ...
    def FromNanoseconds(self, nanos: int) -> None: ...
    def FromMicroseconds(self, micros: int) -> None: ...
    def FromMilliseconds(self, millis: int) -> None: ...
    def FromSeconds(self, seconds: int) -> None: ...
    def ToDatetime(self, tzinfo: tzinfo | None = None) -> datetime: ...
    def FromDatetime(self, dt: datetime) -> None: ...
    def __add__(self, value: Duration | timedelta) -> datetime: ...
    def __radd__(self, value: tAny) -> datetime: ...
    def __sub__(self, value: Timestamp | Duration | timedelta) -> datetime | timedelta: ...
    def __rsub__(self, dt: datetime) -> timedelta: ...

class Duration:
    __slots__ = ()
    def ToJsonString(self) -> str: ...
    seconds: int
    nanos: int
    def FromJsonString(self, value: str) -> None: ...
    def ToNanoseconds(self) -> int: ...
    def ToMicroseconds(self) -> int: ...
    def ToMilliseconds(self) -> int: ...
    def ToSeconds(self) -> int: ...
    def FromNanoseconds(self, nanos: int) -> None: ...
    def FromMicroseconds(self, micros: int) -> None: ...
    def FromMilliseconds(self, millis: int) -> None: ...
    def FromSeconds(self, seconds: int) -> None: ...
    def ToTimedelta(self) -> timedelta: ...
    def FromTimedelta(self, td: timedelta) -> None: ...
    def __add__(self, value: Timestamp | timedelta) -> datetime | timedelta: ...
    def __radd__(self, value: tAny) -> datetime | timedelta: ...
    def __sub__(self, value: Duration | timedelta) -> timedelta: ...
    def __rsub__(self, value: datetime | timedelta) -> datetime | timedelta: ...

class FieldMask:
    __slots__ = ()
    def ToJsonString(self) -> str: ...
    def FromJsonString(self, value: str) -> None: ...
    def IsValidForDescriptor(self, message_descriptor: Descriptor) -> bool: ...
    def AllFieldsFromDescriptor(self, message_descriptor: Descriptor) -> None: ...
    def CanonicalFormFromMask(self, mask: FieldMask) -> None: ...
    def Union(self, mask1: FieldMask, mask2: FieldMask) -> None: ...
    def Intersect(self, mask1: FieldMask, mask2: FieldMask) -> None: ...
    def MergeMessage(
        self, source: _Message, destination: _Message, replace_message_field: bool = False, replace_repeated_field: bool = False
    ) -> None: ...

_StructValue: TypeAlias = struct_pb2.Struct | struct_pb2.ListValue | str | float | bool | None
_StructValueArg: TypeAlias = _StructValue | Mapping[str, _StructValueArg] | Sequence[_StructValueArg]

class Struct:
    __slots__: tuple[str, ...] = ()
    def __getitem__(self, key: str) -> _StructValue: ...
    def __setitem__(self, key: str, value: _StructValueArg) -> None: ...
    def __delitem__(self, key: str) -> None: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[str]: ...
    def keys(self) -> KeysView[str]: ...
    def values(self) -> list[_StructValue]: ...
    def items(self) -> list[tuple[str, _StructValue]]: ...
    def get_or_create_list(self, key: str) -> struct_pb2.ListValue: ...
    def get_or_create_struct(self, key: str) -> struct_pb2.Struct: ...
    def update(self, dictionary: SupportsItems[str, _StructValueArg]) -> None: ...

class ListValue:
    __slots__: tuple[str, ...] = ()
    def __len__(self) -> int: ...
    def append(self, value: _StructValue) -> None: ...
    def extend(self, elem_seq: Iterable[_StructValue]) -> None: ...
    def __getitem__(self, index: int) -> _StructValue: ...
    def __setitem__(self, index: int, value: _StructValueArg) -> None: ...
    def __delitem__(self, key: int) -> None: ...
    # Doesn't actually exist at runtime; needed so type checkers understand the class is iterable
    def __iter__(self) -> Iterator[_StructValue]: ...
    def items(self) -> Iterator[_StructValue]: ...
    def add_struct(self) -> struct_pb2.Struct: ...
    def add_list(self) -> struct_pb2.ListValue: ...

WKTBASES: dict[str, type[tAny]]
