from collections.abc import Callable, Iterable, Mapping, Sequence
from typing import Any, ClassVar, final
from typing_extensions import Self, disjoint_base

from google.protobuf.descriptor_pb2 import (
    DescriptorProto,
    EnumDescriptorProto,
    EnumOptions,
    EnumValueOptions,
    FeatureSetDefaults,
    FieldOptions,
    FileDescriptorProto,
    FileOptions,
    MessageOptions,
    MethodDescriptorProto,
    MethodOptions,
    OneofOptions,
    ServiceDescriptorProto,
    ServiceOptions,
)

default_pool: DescriptorPool

@final
class Arena: ...

@final
class Descriptor:
    containing_type: Descriptor | None
    enum_types: Sequence[EnumDescriptor]
    enum_types_by_name: Mapping[str, EnumDescriptor]
    enum_values_by_name: dict[str, EnumValueDescriptor]
    extension_ranges: list[tuple[int, int]]
    extensions: Sequence[FieldDescriptor]
    extensions_by_name: Mapping[str, FieldDescriptor]
    fields: Sequence[FieldDescriptor]
    fields_by_camelcase_name: Mapping[str, FieldDescriptor]
    fields_by_name: Mapping[str, FieldDescriptor]
    fields_by_number: Mapping[int, FieldDescriptor]
    file: FileDescriptor
    full_name: str
    has_options: bool
    is_extendable: bool
    name: str
    nested_types: Sequence[Descriptor]
    nested_types_by_name: Mapping[str, Descriptor]
    oneofs: Sequence[OneofDescriptor]
    oneofs_by_name: Mapping[str, OneofDescriptor]
    def __new__(cls, *args, **kwargs) -> Self: ...
    def CopyToProto(self, proto: DescriptorProto, /) -> None: ...
    def EnumValueName(self, enum: str, value: int) -> str: ...
    def GetOptions(self) -> MessageOptions: ...

@final
class DescriptorPool:
    def __new__(cls, *args, **kwargs) -> Self: ...
    def Add(self, file_desc_proto: FileDescriptorProto, /) -> None: ...
    def AddSerializedFile(self, serialized_file_desc_proto: bytes, /) -> FileDescriptor: ...
    def FindAllExtensions(self, message_descriptor: Descriptor, /) -> list[FieldDescriptor]: ...
    def FindEnumTypeByName(self, full_name: str, /) -> EnumDescriptor: ...
    def FindExtensionByName(self, full_name: str, /) -> FieldDescriptor: ...
    def FindExtensionByNumber(self, message_descriptor: Descriptor, number: int, /) -> FieldDescriptor: ...
    def FindFieldByName(self, full_name: str, /) -> FieldDescriptor: ...
    def FindFileByName(self, file_name: str, /) -> FileDescriptor: ...
    def FindFileContainingSymbol(self, symbol: str, /) -> FileDescriptor: ...
    def FindMessageTypeByName(self, full_name: str, /) -> Descriptor: ...
    def FindMethodByName(self, full_name: str, /) -> MethodDescriptor: ...
    def FindOneofByName(self, full_name: str, /) -> OneofDescriptor: ...
    def FindServiceByName(self, full_name: str, /) -> ServiceDescriptor: ...
    def SetFeatureSetDefaults(self, defaults: FeatureSetDefaults, /) -> None: ...

@final
class EnumDescriptor:
    containing_type: Descriptor | None
    file: FileDescriptor
    full_name: str
    has_options: bool
    is_closed: bool
    name: str
    values: Sequence[EnumValueDescriptor]
    values_by_name: Mapping[str, EnumValueDescriptor]
    values_by_number: Mapping[int, EnumValueDescriptor]
    def __new__(cls, *args, **kwargs) -> Self: ...
    def CopyToProto(self, proto: EnumDescriptorProto, /) -> None: ...
    def GetOptions(self) -> EnumOptions: ...

@final
class EnumValueDescriptor:
    has_options: bool
    index: int
    name: str
    number: int
    type: EnumDescriptor
    def __new__(cls, *args, **kwargs) -> Self: ...
    def GetOptions(self) -> EnumValueOptions: ...

@final
class ExtensionDict:
    def __contains__(self, extension_handle: FieldDescriptor, /) -> bool: ...
    def __delitem__(self, extension_handle: FieldDescriptor, /) -> None: ...
    def __eq__(self, other: object, /) -> bool: ...
    def __ge__(self, other: object, /) -> bool: ...
    def __getitem__(self, extension_handle: FieldDescriptor, /) -> Any: ...  # Any: Message, scalar, or container
    def __gt__(self, other: object, /) -> bool: ...
    def __iter__(self) -> ExtensionIterator: ...
    def __le__(self, other: object, /) -> bool: ...
    def __len__(self) -> int: ...
    def __lt__(self, other: object, /) -> bool: ...
    def __ne__(self, other: object, /) -> bool: ...
    def __setitem__(self, extension_handle: FieldDescriptor, value: Any, /) -> None: ...  # Any: Message, scalar, or container

@final
class ExtensionIterator:
    def __iter__(self) -> Self: ...
    def __next__(self) -> FieldDescriptor: ...

@final
class FieldDescriptor:
    CPPTYPE_BOOL: ClassVar[int] = ...
    CPPTYPE_BYTES: ClassVar[int] = ...
    CPPTYPE_DOUBLE: ClassVar[int] = ...
    CPPTYPE_ENUM: ClassVar[int] = ...
    CPPTYPE_FLOAT: ClassVar[int] = ...
    CPPTYPE_INT32: ClassVar[int] = ...
    CPPTYPE_INT64: ClassVar[int] = ...
    CPPTYPE_MESSAGE: ClassVar[int] = ...
    CPPTYPE_STRING: ClassVar[int] = ...
    CPPTYPE_UINT32: ClassVar[int] = ...
    CPPTYPE_UINT64: ClassVar[int] = ...
    LABEL_OPTIONAL: ClassVar[int] = ...
    LABEL_REPEATED: ClassVar[int] = ...
    LABEL_REQUIRED: ClassVar[int] = ...
    TYPE_BOOL: ClassVar[int] = ...
    TYPE_BYTES: ClassVar[int] = ...
    TYPE_DOUBLE: ClassVar[int] = ...
    TYPE_ENUM: ClassVar[int] = ...
    TYPE_FIXED32: ClassVar[int] = ...
    TYPE_FIXED64: ClassVar[int] = ...
    TYPE_FLOAT: ClassVar[int] = ...
    TYPE_GROUP: ClassVar[int] = ...
    TYPE_INT32: ClassVar[int] = ...
    TYPE_INT64: ClassVar[int] = ...
    TYPE_MESSAGE: ClassVar[int] = ...
    TYPE_SFIXED32: ClassVar[int] = ...
    TYPE_SFIXED64: ClassVar[int] = ...
    TYPE_SINT32: ClassVar[int] = ...
    TYPE_SINT64: ClassVar[int] = ...
    TYPE_STRING: ClassVar[int] = ...
    TYPE_UINT32: ClassVar[int] = ...
    TYPE_UINT64: ClassVar[int] = ...
    camelcase_name: str
    containing_oneof: OneofDescriptor | None
    containing_type: Descriptor | None
    cpp_type: int
    default_value: Any  # Any: str, int, float, bytes, or bool
    enum_type: EnumDescriptor | None
    extension_scope: Descriptor | None
    file: FileDescriptor
    full_name: str
    has_default_value: bool
    has_options: bool
    has_presence: bool
    index: int
    is_extension: bool
    is_packed: bool
    is_repeated: bool
    is_required: bool
    json_name: str
    message_type: Descriptor | None
    name: str
    number: int
    type: int
    def __new__(cls, *args, **kwargs) -> Self: ...
    def GetOptions(self) -> FieldOptions: ...

@final
class FileDescriptor:
    dependencies: Sequence[FileDescriptor]
    enum_types_by_name: Mapping[str, EnumDescriptor]
    extensions_by_name: Mapping[str, FieldDescriptor]
    has_options: bool
    message_types_by_name: Mapping[str, Descriptor]
    name: str
    package: str
    pool: DescriptorPool
    public_dependencies: Sequence[FileDescriptor]
    serialized_pb: bytes
    services_by_name: Mapping[str, ServiceDescriptor]
    def __new__(cls, *args, **kwargs) -> Self: ...
    def CopyToProto(self, proto: FileDescriptorProto, /) -> None: ...
    def GetOptions(self) -> FileOptions: ...

@final
class MapIterator:
    def __iter__(self) -> Self: ...
    def __next__(self) -> bool | int | str: ...

@final
class Message:
    Extensions: ExtensionDict
    def __init__(self, *args, **kwargs) -> None: ...
    def __contains__(self, field_name_or_key: str, /) -> bool: ...
    def __deepcopy__(self, memo: Any = None) -> Self: ...
    def __delattr__(self, name: str, /) -> None: ...
    def __eq__(self, other: object, /) -> bool: ...
    def __ge__(self, other: object, /) -> bool: ...
    def __gt__(self, other: object, /) -> bool: ...
    def __le__(self, other: object, /) -> bool: ...
    def __lt__(self, other: object, /) -> bool: ...
    def __ne__(self, other: object, /) -> bool: ...
    def __setattr__(self, name: str, value: Any, /) -> None: ...  # Any: str, int, float, bytes, bool, or Message
    def MergeFrom(self, other_msg: Message, /) -> None: ...
    def CopyFrom(self, other_msg: Message, /) -> None: ...
    def Clear(self) -> None: ...
    def SetInParent(self) -> None: ...
    def IsInitialized(self, errors: list[str] | None = None) -> bool: ...
    def MergeFromString(self, serialized: bytes, /) -> int: ...
    def ParseFromString(self, serialized: bytes, /) -> int: ...
    def SerializeToString(self, *, deterministic: bool = ...) -> bytes: ...
    def SerializePartialToString(self, *, deterministic: bool = ...) -> bytes: ...
    def ListFields(self) -> list[tuple[FieldDescriptor, Any]]: ...  # Any: str, int, float, bytes, bool, or Message
    def HasField(self, field_name: str, /) -> bool: ...
    def ClearField(self, field_name: str, /) -> None: ...
    def WhichOneof(self, oneof_group: str, /) -> str | None: ...
    def HasExtension(self, field_descriptor: FieldDescriptor, /) -> bool: ...
    def ClearExtension(self, field_descriptor: FieldDescriptor, /) -> None: ...
    def UnknownFields(self) -> UnknownFieldSet: ...
    def DiscardUnknownFields(self) -> None: ...
    def ByteSize(self) -> int: ...
    @classmethod
    def FromString(cls, s: bytes, /) -> Self: ...
    def FindInitializationErrors(self) -> list[str]: ...

@disjoint_base
class MessageMeta(type): ...

@final
class MethodDescriptor:
    client_streaming: bool
    containing_service: ServiceDescriptor
    full_name: str
    has_options: bool
    index: int
    input_type: Descriptor
    name: str
    output_type: Descriptor
    server_streaming: bool
    def __new__(cls, *args, **kwargs) -> Self: ...
    def CopyToProto(self, proto: MethodDescriptorProto, /) -> None: ...
    def GetOptions(self) -> MethodOptions: ...

@final
class OneofDescriptor:
    containing_type: Descriptor
    fields: Sequence[FieldDescriptor]
    full_name: str
    has_options: bool
    index: int
    name: str
    def __new__(cls, *args, **kwargs) -> Self: ...
    def GetOptions(self) -> OneofOptions: ...

@final
class RepeatedCompositeContainer:
    def __new__(cls, *args, **kwargs) -> Self: ...
    def MergeFrom(self, other: RepeatedCompositeContainer | Iterable[Message], /) -> None: ...
    def add(self, **kwargs: Any) -> Message: ...  # Any: field names and values
    def append(self, value: Message, /) -> None: ...
    def extend(self, values: Iterable[Message], /) -> None: ...
    def insert(self, key: int, value: Message, /) -> None: ...
    def pop(self, key: int = -1, /) -> Message: ...
    def remove(self, value: Message, /) -> None: ...
    def reverse(self) -> None: ...
    def sort(self, *, key: Callable[[Any], Any] | None = None, reverse: bool = False) -> None: ...
    def clear(self) -> None: ...
    def __deepcopy__(self, memo: Any = None) -> RepeatedCompositeContainer: ...
    def __delitem__(self, key: int | slice, /) -> None: ...
    def __eq__(self, other: object, /) -> bool: ...
    def __ge__(self, other: object, /) -> bool: ...
    def __getitem__(self, index: int | slice, /) -> Message: ...
    def __gt__(self, other: object, /) -> bool: ...
    def __le__(self, other: object, /) -> bool: ...
    def __len__(self) -> int: ...
    def __lt__(self, other: object, /) -> bool: ...
    def __ne__(self, other: object, /) -> bool: ...
    def __setitem__(self, index: int | slice, value: Message, /) -> None: ...

@final
class RepeatedScalarContainer:
    def __new__(cls, *args, **kwargs) -> Self: ...
    def MergeFrom(self, other: Any, /) -> None: ...  # Any: bool, int, float, str, or bytes
    def append(self, value: Any, /) -> None: ...
    def extend(self, values: Any, /) -> None: ...
    def insert(self, key: int, value: Any, /) -> None: ...
    def pop(self, key: int = -1, /) -> Any: ...
    def remove(self, value: Any, /) -> None: ...
    def reverse(self) -> None: ...
    def sort(self, *, key: Callable[[Any], Any] | None = None, reverse: bool = False) -> None: ...
    def clear(self) -> None: ...
    def __array__(self, dtype: Any = None, copy: bool | None = None) -> Any: ...  # Any: numpy types
    def __deepcopy__(self, memo: Any = None) -> RepeatedScalarContainer: ...
    def __delitem__(self, key: int | slice, /) -> None: ...
    def __eq__(self, other: object, /) -> bool: ...
    def __ge__(self, other: object, /) -> bool: ...
    def __getitem__(self, index: int | slice, /) -> Any: ...
    def __gt__(self, other: object, /) -> bool: ...
    def __le__(self, other: object, /) -> bool: ...
    def __len__(self) -> int: ...
    def __lt__(self, other: object, /) -> bool: ...
    def __ne__(self, other: object, /) -> bool: ...
    def __reduce__(self) -> tuple[Any, ...]: ...
    def __setitem__(self, index: int | slice, value: Any, /) -> None: ...

@final
class ServiceDescriptor:
    file: FileDescriptor
    full_name: str
    has_options: bool
    index: int
    methods: Sequence[MethodDescriptor]
    methods_by_name: Mapping[str, MethodDescriptor]
    name: str
    def __new__(cls, *args, **kwargs) -> Self: ...
    def CopyToProto(self, proto: ServiceDescriptorProto, /) -> None: ...
    def FindMethodByName(self, name: str, /) -> MethodDescriptor: ...
    def GetOptions(self) -> ServiceOptions: ...

@final
class UnknownFieldSet:
    def __new__(cls, *args, **kwargs) -> Self: ...
    def __getitem__(self, index: int, /) -> Any: ...  # Any: internal unknown field object
    def __len__(self) -> int: ...

def SetAllowOversizeProtos(allow: bool, /) -> None: ...
