from __future__ import annotations
import sys
from typing import Generator, Dict, List, TYPE_CHECKING, Optional
from enum import Flag, auto

from lldb import (
    SBData,
    SBError,
    eBasicTypeLong,
    eBasicTypeUnsignedLong,
    eBasicTypeUnsignedChar,
    eBasicTypeUnsignedShort,
    eBasicTypeUnsignedLongLong,
    eBasicTypeSignedChar,
    eBasicTypeShort,
    eBasicTypeLongLong,
    eBasicTypeFloat,
    eBasicTypeDouble,
    eBasicTypeHalf,
    eBasicTypeChar32,
    eFormatChar,
    eTypeIsInteger,
)

from rust_types import is_tuple_fields

if TYPE_CHECKING:
    from lldb import SBValue, SBType, SBTypeStaticField, SBTarget, SBProcess

# from lldb.formatters import Logger

####################################################################################################
# This file contains two kinds of pretty-printers: summary and synthetic.
#
# Important classes from LLDB module:
#   SBValue: the value of a variable, a register, or an expression
#   SBType:  the data type; each SBValue has a corresponding SBType
#
# Summary provider is a function with the type `(SBValue, dict) -> str`.
#   The first parameter is the object encapsulating the actual variable being displayed;
#   The second parameter is an internal support parameter used by LLDB, and you should not touch it.
#
# Synthetic children is the way to provide a children-based representation of the object's value.
# Synthetic provider is a class that implements the following interface:
#
#     class SyntheticChildrenProvider:
#         def __init__(self, SBValue, dict)
#         def num_children(self)
#         def get_child_index(self, str)
#         def get_child_at_index(self, int)
#         def update(self)
#         def has_children(self)
#         def get_value(self)
#
#
# You can find more information and examples here:
#   1. https://lldb.llvm.org/varformats.html
#   2. https://lldb.llvm.org/use/python-reference.html
#   3. https://github.com/llvm/llvm-project/blob/llvmorg-8.0.1/lldb/www/python_reference/lldb.formatters.cpp-pysrc.html
#   4. https://github.com/llvm-mirror/lldb/tree/master/examples/summaries/cocoa
####################################################################################################

PY3 = sys.version_info[0] == 3


class LLDBFeature(Flag):
    """Used to track which features we rely on and whether or not we can access them. The global
    `lldb_providers.FEATURE_FLAGS` is initialized in `lldb_lookup.__lldb_init_module` and is
    expected not to change after that point.

    This is used rather than `debugger.GetVersionString` because Apple's fork of LLDB (used for
    xcode) uses a non-standard versioning scheme that has no relation to LLVM's.
    """

    StaticFields = auto()
    """Added in LLDB 18. Adds functions to `SBType` the inspection of a struct's static fields."""
    TypeRecognizers = auto()
    """Added in LLDB 19. Callback-based type matching for synthetic/summary providers."""
    Float128 = auto()
    """Added in LLDB 22.1. Adds builtin support for Float 128's, including an `eBasicTypeFloat128`,
    a formatter, and handlers in `TypeSystemClang`"""


FEATURE_FLAGS: LLDBFeature = LLDBFeature(0)


class LLDBOpaque:
    """
    An marker type for use in type hints to denote LLDB bookkeeping variables. Values marked with
    this type should never be used except when passing as an argument to an LLDB function.
    """


class ValueBuilder:
    def __init__(self, valobj: SBValue):
        self.valobj = valobj
        process = valobj.GetProcess()
        self.endianness = process.GetByteOrder()
        self.pointer_size = process.GetAddressByteSize()

    def from_int(self, name: str, value: int) -> SBValue:
        type = self.valobj.GetType().GetBasicType(eBasicTypeLong)
        data = SBData.CreateDataFromSInt64Array(
            self.endianness,
            self.pointer_size,
            [value],
        )
        return self.valobj.CreateValueFromData(name, data, type)

    def from_uint(self, name: str, value: int) -> SBValue:
        type = self.valobj.GetType().GetBasicType(eBasicTypeUnsignedLong)
        data = SBData.CreateDataFromUInt64Array(
            self.endianness,
            self.pointer_size,
            [value],
        )
        return self.valobj.CreateValueFromData(name, data, type)


def unwrap_unique_or_non_null(unique_or_nonnull: SBValue) -> SBValue:
    # BACKCOMPAT: rust 1.32
    # https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067
    # BACKCOMPAT: rust 1.60
    # https://github.com/rust-lang/rust/commit/2a91eeac1a2d27dd3de1bf55515d765da20fd86f
    ptr = unique_or_nonnull.GetChildMemberWithName("pointer")
    return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0)


def unwrap_scalar_wrappers(wrapper: SBValue) -> SBValue:
    while (wrapper.type.GetTypeFlags() & eTypeIsInteger) == 0:
        wrapper = wrapper.GetChildAtIndex(0)
    return wrapper


class DefaultSyntheticProvider:
    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        # logger = Logger.Logger()
        # logger >> "Default synthetic provider for " + str(valobj.GetName())
        self.valobj = valobj
        self.is_ptr = valobj.GetType().IsPointerType()

    def num_children(self) -> int:
        return self.valobj.GetNumChildren()

    def get_child_index(self, name: str) -> int:
        return self.valobj.GetIndexOfChildWithName(name)

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        return self.valobj.GetChildAtIndex(index)

    def update(self):
        pass

    def has_children(self) -> bool:
        return self.valobj.MightHaveChildren()

    def get_value(self):
        return self.valobj.value


class EmptySyntheticProvider:
    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        # logger = Logger.Logger()
        # logger >> "[EmptySyntheticProvider] for " + str(valobj.GetName())
        self.valobj = valobj

    def num_children(self) -> int:
        return 0

    def get_child_index(self, name: str) -> int:
        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        return None

    def update(self):
        pass

    def has_children(self) -> bool:
        return False


def get_template_args(type_name: str) -> Generator[str, None, None]:
    """
    Takes a type name `T<A, tuple$<B, C>, D>` and returns a list of its generic args
    `["A", "tuple$<B, C>", "D"]`.

    String-based replacement for LLDB's `SBType.template_args`, as LLDB is currently unable to
    populate this field for targets with PDB debug info. Also useful for manually altering the type
    name of generics (e.g. `Vec<ref$<str$> >` -> `Vec<&str>`).

    Each element of the returned list can be looked up for its `SBType` value via
    `SBTarget.FindFirstType()`
    """
    level = 0
    start = 0
    for i, c in enumerate(type_name):
        if c == "<":
            level += 1
            if level == 1:
                start = i + 1
        elif c == ">":
            level -= 1
            if level == 0:
                yield type_name[start:i].strip()
        elif c == "," and level == 1:
            yield type_name[start:i].strip()
            start = i + 1


MSVC_PTR_PREFIX: List[str] = ["ref$<", "ref_mut$<", "ptr_const$<", "ptr_mut$<"]

PRIMITIVE_TYPES: Dict[str, int] = {
    "u8": eBasicTypeUnsignedChar,
    "u16": eBasicTypeUnsignedShort,
    "u32": eBasicTypeUnsignedLong,
    "u64": eBasicTypeUnsignedLongLong,
    "i8": eBasicTypeSignedChar,
    "i16": eBasicTypeShort,
    "i32": eBasicTypeLong,
    "i64": eBasicTypeLongLong,
    "f16": eBasicTypeHalf,
    "f32": eBasicTypeFloat,
    "f64": eBasicTypeDouble,
    "char": eBasicTypeChar32,
}


def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType:
    """
    RECURSIVE when arrays or references are nested (e.g. `ref$<ref$<u8> >`, `array$<ref$<u8> >`)

    Takes the template arg's name (likely from `get_template_args`) and finds/creates its
    corresponding SBType.

    For non-reference/pointer/array types this is identical to calling
    `target.FindFirstType(arg_name)`

    LLDB internally interprets refs, pointers, and arrays C-style (`&u8` -> `u8 *`,
    `*const u8` -> `u8 *`, `[u8; 5]` -> `u8 [5]`). Looking up these names still doesn't work in the
    current version of LLDB, so instead the types are generated via `base_type.GetPointerType()` and
    `base_type.GetArrayType()`, which bypass the PDB file and ask clang directly for the type node.
    """

    # As of LLDB 22, finding primitives based on `FindFirstType` with their rust name no longer
    # works. Instead, we can look them up by their `eBasicType` equivalent. For usize and isize,
    # we convert them to their bit-sized counterpart before the lookup
    if arg_name == "isize" or arg_name == "usize":
        equivalent = f"{arg_name[0]}{target.GetAddressByteSize() * 8}"
        return target.GetBasicType(PRIMITIVE_TYPES[equivalent])

    if (basic_type := PRIMITIVE_TYPES.get(arg_name)) is not None:
        return target.GetBasicType(basic_type)

    if arg_name == "f128" and LLDBFeature.Float128 in FEATURE_FLAGS:
        from lldb import eBasicTypeFloat128

        return target.GetBasicType(eBasicTypeFloat128)

    result = target.FindFirstType(arg_name)

    if result.IsValid():
        return result

    for prefix in MSVC_PTR_PREFIX:
        if arg_name.startswith(prefix):
            arg_name = arg_name[len(prefix) : -1].strip()

            result = resolve_msvc_template_arg(arg_name, target)
            return result.GetPointerType()

    if arg_name.startswith("array$<"):
        template_args = get_template_args(arg_name)

        element_name = next(template_args)
        length = next(template_args)

        result = resolve_msvc_template_arg(element_name, target)

        return result.GetArrayType(int(length))

    return result


def StructSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    # structs need the field name before the field value
    output = (
        f"{valobj.GetChildAtIndex(i).GetName()}:{child}"
        for i, child in enumerate(aggregate_field_summary(valobj, _dict))
    )

    return "{" + ", ".join(output) + "}"


def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque):
    return "(" + ", ".join(aggregate_field_summary(valobj, _dict)) + ")"


def aggregate_field_summary(valobj: SBValue, _dict) -> Generator[str, None, None]:
    for i in range(0, valobj.GetNumChildren()):
        child: SBValue = valobj.GetChildAtIndex(i)
        summary = child.summary
        if summary is None:
            summary = child.value
            if summary is None:
                if is_tuple_fields(child.GetType().fields):
                    summary = TupleSummaryProvider(child, _dict)
                else:
                    summary = StructSummaryProvider(child, _dict)
        yield summary


def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    return "size=" + str(valobj.GetNumChildren())


def vec_to_string(vec: SBValue) -> str:
    length = vec.GetNumChildren()
    chars = [vec.GetChildAtIndex(i).GetValueAsUnsigned() for i in range(length)]
    return (
        bytes(chars).decode(errors="replace")
        if PY3
        else "".join(chr(char) for char in chars)
    )


def read_string(
    process: SBProcess, address: int, length: int, error: Optional[SBError] = None
) -> str:
    """Reads a string from running process's memory. If `error` is passed in, it will be passed
    to the `SBProcess.ReadMemory` call, and will reflect any errors after the function is called.

    If any error or exception occurs, a placeholder byte array of the form "<error: [reason]>" will
    be returned instead."""

    if error is None:
        error = SBError()
    try:
        data = process.ReadMemory(address, length, error)
        if error.Success():
            return '"' + data.decode("utf-8", "replace") + '"'
        else:
            return f"<error: {error.GetCString()}>"
    except Exception as e:
        print(f"Unable to generate String summary: {e.__cause__}")
        return "<error: Unable to read memory>"


def StdStringSummaryProvider(valobj: SBValue, dict: LLDBOpaque):
    inner_vec = (
        valobj.GetNonSyntheticValue()
        .GetChildMemberWithName("vec")
        .GetNonSyntheticValue()
    )

    pointer = (
        inner_vec.GetChildMemberWithName("buf")
        .GetChildMemberWithName("inner")
        .GetChildMemberWithName("ptr")
        .GetChildMemberWithName("pointer")
        .GetChildMemberWithName("pointer")
    )

    length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()
    capacity = (
        inner_vec.GetChildMemberWithName("buf")
        .GetChildMemberWithName("cap")
        .GetValueAsUnsigned()
    )

    if length <= 0:
        return '""'

    no_hi_bit_max: int = 1 << ((pointer.GetByteSize() * 8) - 1)
    # technically length isn't a NoHighBit<usize>, but length should always be <= capacity
    if length >= no_hi_bit_max or capacity >= no_hi_bit_max:
        return "<error: invalid len/capacity>"
    if pointer.GetValueAsUnsigned() == 0:
        return "<error: String pointer is null>"

    process = pointer.GetProcess()

    return read_string(process, pointer.GetValueAsAddress(), length)


def StdOsStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    # logger = Logger.Logger()
    # logger >> "[StdOsStringSummaryProvider] for " + str(valobj.GetName())
    buf = valobj.GetChildAtIndex(0).GetChildAtIndex(0)
    is_windows = "Wtf8Buf" in buf.type.name
    vec = buf.GetChildAtIndex(0) if is_windows else buf
    return '"%s"' % vec_to_string(vec)


def StdStrSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    # logger = Logger.Logger()
    # logger >> "[StdStrSummaryProvider] for " + str(valobj.GetName())

    # the code below assumes non-synthetic value, this makes sure the assumption holds
    valobj = valobj.GetNonSyntheticValue()

    length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
    if length == 0:
        return '""'

    data_ptr = valobj.GetChildMemberWithName("data_ptr")

    start = data_ptr.GetValueAsUnsigned()
    error = SBError()
    process = data_ptr.GetProcess()
    data = process.ReadMemory(start, length, error)
    data = data.decode(encoding="UTF-8") if PY3 else data
    return '"%s"' % data


def StdPathBufSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    # logger = Logger.Logger()
    # logger >> "[StdPathBufSummaryProvider] for " + str(valobj.GetName())
    return StdOsStringSummaryProvider(valobj.GetChildMemberWithName("inner"), _dict)


def StdPathSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    # logger = Logger.Logger()
    # logger >> "[StdPathSummaryProvider] for " + str(valobj.GetName())
    length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
    if length == 0:
        return '""'

    data_ptr = valobj.GetChildMemberWithName("data_ptr")

    start = data_ptr.GetValueAsUnsigned()
    process = data_ptr.GetProcess()

    return read_string(process, start, length)


def sequence_formatter(output: str, valobj: SBValue, _dict: LLDBOpaque):
    length: int = valobj.GetNumChildren()

    long: bool = False
    for i in range(0, length):
        if len(output) > 32:
            long = True
            break

        child: SBValue = valobj.GetChildAtIndex(i)

        summary = child.summary
        if summary is None:
            summary = child.value
            if summary is None:
                summary = "{...}"
        output += f"{summary}, "
    if long:
        output = f"(len: {length}) " + output + "..."
    else:
        output = output[:-2]

    return output


class StructSyntheticProvider:
    """Pretty-printer for structs and struct enum variants"""

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_variant: bool = False):
        # logger = Logger.Logger()
        self.valobj = valobj
        self.is_variant = is_variant
        self.type = valobj.GetType()
        self.fields = {}

        if is_variant:
            self.fields_count = self.type.GetNumberOfFields() - 1
            real_fields = self.type.fields[1:]
        else:
            self.fields_count = self.type.GetNumberOfFields()
            real_fields = self.type.fields

        for number, field in enumerate(real_fields):
            self.fields[field.name] = number

    def num_children(self) -> int:
        return self.fields_count

    def get_child_index(self, name: str) -> int:
        return self.fields.get(name, -1)

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if self.is_variant:
            field = self.type.GetFieldAtIndex(index + 1)
        else:
            field = self.type.GetFieldAtIndex(index)
        return self.valobj.GetChildMemberWithName(field.name)

    def update(self):
        # type: () -> None
        pass

    def has_children(self) -> bool:
        return True


class StdStringSyntheticProvider:
    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        ptr_size = valobj.GetTarget().GetAddressByteSize() * 8
        self.no_hi_bit_max = 1 << (ptr_size - 1)

        self.update()

    def update(self):
        inner_vec = self.valobj.GetChildMemberWithName("vec").GetNonSyntheticValue()
        self.data_ptr = (
            inner_vec.GetChildMemberWithName("buf")
            .GetChildMemberWithName("inner")
            .GetChildMemberWithName("ptr")
            .GetChildMemberWithName("pointer")
            .GetChildMemberWithName("pointer")
        )

        self.capacity = (
            inner_vec.GetChildMemberWithName("buf")
            .GetChildMemberWithName("cap")
            .GetValueAsUnsigned()
        )

        # As of 4/18/2026, LLDB cannot accurately determine the difference between Some("") and None
        # this just makes sure we're not trying to access data when the string is clearly in an
        # invalid state.
        if (
            self.capacity >= self.no_hi_bit_max
            or self.data_ptr.GetValueAsUnsigned() == 0
        ):
            self.capacity = 0
            self.length = 0
        else:
            self.length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()

        self.element_type = self.data_ptr.GetType().GetPointeeType()

    def has_children(self) -> bool:
        return True

    def num_children(self) -> int:
        return self.length

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)

        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if not 0 <= index < self.length:
            return None
        start = self.data_ptr.GetValueAsUnsigned()
        address = start + index
        element = self.data_ptr.CreateValueFromAddress(
            f"[{index}]", address, self.element_type
        )
        element.SetFormat(eFormatChar)
        return element


class MSVCStrSyntheticProvider:
    __slots__ = ["valobj", "data_ptr", "length"]

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        self.update()

    def update(self):
        self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr")
        self.length = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned()

    def has_children(self) -> bool:
        return True

    def num_children(self) -> int:
        return self.length

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)

        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if not 0 <= index < self.length:
            return None
        start = self.data_ptr.GetValueAsUnsigned()
        address = start + index
        element = self.data_ptr.CreateValueFromAddress(
            f"[{index}]", address, self.data_ptr.GetType().GetPointeeType()
        )
        return element

    def get_type_name(self):
        if self.valobj.GetTypeName().startswith("ref_mut"):
            return "&mut str"
        else:
            return "&str"


def _getVariantName(variant: SBValue) -> str:
    """
    Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
    we can extract `TheVariantName` from it for display purpose.
    """
    s = variant.GetType().GetName()
    if not s.endswith("$Variant"):
        return ""

    # trim off path and "$Variant"
    # len("$Variant") == 8
    return s.rsplit("::", 1)[1][:-8]


class ClangEncodedEnumProvider:
    """Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""

    valobj: SBValue
    variant: SBValue
    value: SBValue

    DISCRIMINANT_MEMBER_NAME = "$discr$"
    VALUE_MEMBER_NAME = "value"

    __slots__ = ("valobj", "variant", "value")

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        self.update()

    def has_children(self) -> bool:
        return self.value.MightHaveChildren()

    def num_children(self) -> int:
        return self.value.GetNumChildren()

    def get_child_index(self, name: str) -> int:
        return self.value.GetIndexOfChildWithName(name)

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        return self.value.GetChildAtIndex(index)

    def update(self):
        all_variants = self.valobj.GetChildAtIndex(0)
        index = self._getCurrentVariantIndex(all_variants)
        self.variant = all_variants.GetChildAtIndex(index)
        self.value = self.variant.GetChildMemberWithName(
            ClangEncodedEnumProvider.VALUE_MEMBER_NAME
        )
        if (synth := self.value.GetSyntheticValue()).IsValid():
            self.value = synth

    def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
        default_index = 0
        for i in range(all_variants.GetNumChildren()):
            variant = all_variants.GetChildAtIndex(i)
            discr = variant.GetChildMemberWithName(
                ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME
            )
            if discr.IsValid():
                discr_unsigned_value = discr.GetValueAsUnsigned()
                if variant.GetName() == f"$variant${discr_unsigned_value}":
                    return i
            else:
                default_index = i
        return default_index


def ClangEncodedEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    if valobj.TypeIsPointerType():
        valobj = valobj.Dereference()
    enum_synth = ClangEncodedEnumProvider(valobj.GetNonSyntheticValue(), _dict)
    variant = enum_synth.variant
    name = _getVariantName(variant)

    if valobj.GetNumChildren() == 0:
        return name

    child_name: str = valobj.GetChildAtIndex(0).name
    if child_name == "0" or child_name == "__0":
        # enum variant is a tuple struct
        return name + TupleSummaryProvider(valobj, _dict)
    else:
        # enum variant is a regular struct
        return name + StructSummaryProvider(valobj, _dict)


class MSVCEnumSyntheticProvider:
    """
    Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
    see:

    https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
    """

    valobj: SBValue
    variant: SBValue
    value: SBValue

    __slots__ = ["valobj", "variant", "value"]

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        # This allows the summary provider to still print something
        # even if we can't find the variant for whatever reason
        self.variant = valobj
        self.value = valobj
        self.update()

    def update(self):
        tag: SBValue = self.valobj.GetChildMemberWithName("tag")

        if tag.IsValid():
            tag: int = tag.GetValueAsUnsigned()
            for child in self.valobj.GetNonSyntheticValue().children:
                if not child.name.startswith("variant"):
                    continue

                variant_type: SBType = child.GetType()
                try:
                    exact: SBTypeStaticField = variant_type.GetStaticFieldWithName(
                        "DISCR_EXACT"
                    )
                except AttributeError:
                    # LLDB versions prior to 19.0.0 do not have the `SBTypeGetStaticField` API.
                    # With current DI generation there's not a great way to provide a "best effort"
                    # evaluation either, so we just return the object itself with no further
                    # attempts to inspect the type information
                    self.variant = self.valobj
                    self.value = self.valobj
                    return

                if exact.IsValid():
                    discr: int = exact.GetConstantValue(
                        self.valobj.target
                    ).GetValueAsUnsigned()
                    if tag == discr:
                        self.variant = child
                        self.value = child.GetChildMemberWithName("value")
                        if (synth := self.value.GetSyntheticValue()).IsValid():
                            self.value = synth

                        return
                else:  # if invalid, DISCR must be a range
                    begin: int = (
                        variant_type.GetStaticFieldWithName("DISCR_BEGIN")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )
                    end: int = (
                        variant_type.GetStaticFieldWithName("DISCR_END")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )

                    # begin isn't necessarily smaller than end, so we must test for both cases
                    if begin < end:
                        if begin <= tag <= end:
                            self.variant = child
                            self.value = child.GetChildMemberWithName("value")
                            if (synth := self.value.GetSyntheticValue()).IsValid():
                                self.value = synth

                            return
                    else:
                        if tag >= begin or tag <= end:
                            self.variant = child
                            self.value = child.GetChildMemberWithName("value")
                            if (synth := self.value.GetSyntheticValue()).IsValid():
                                self.value = synth

                            return
        else:  # if invalid, tag is a 128 bit value
            tag_lo: int = self.valobj.GetChildMemberWithName(
                "tag128_lo"
            ).GetValueAsUnsigned()
            tag_hi: int = self.valobj.GetChildMemberWithName(
                "tag128_hi"
            ).GetValueAsUnsigned()

            tag: int = (tag_hi << 64) | tag_lo

            for child in self.valobj.GetNonSyntheticValue().children:
                if not child.name.startswith("variant"):
                    continue

                variant_type: SBType = child.GetType()
                exact_lo: SBTypeStaticField = variant_type.GetStaticFieldWithName(
                    "DISCR128_EXACT_LO"
                )

                if exact_lo.IsValid():
                    exact_lo: int = exact_lo.GetConstantValue(
                        self.valobj.target
                    ).GetValueAsUnsigned()
                    exact_hi: int = (
                        variant_type.GetStaticFieldWithName("DISCR128_EXACT_HI")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )

                    discr: int = (exact_hi << 64) | exact_lo
                    if tag == discr:
                        self.variant = child
                        self.value = child.GetChildMemberWithName("value")
                        if (synth := self.value.GetSyntheticValue()).IsValid():
                            self.value = synth
                        return
                else:  # if invalid, DISCR must be a range
                    begin_lo: int = (
                        variant_type.GetStaticFieldWithName("DISCR128_BEGIN_LO")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )
                    begin_hi: int = (
                        variant_type.GetStaticFieldWithName("DISCR128_BEGIN_HI")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )

                    end_lo: int = (
                        variant_type.GetStaticFieldWithName("DISCR128_END_LO")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )
                    end_hi: int = (
                        variant_type.GetStaticFieldWithName("DISCR128_END_HI")
                        .GetConstantValue(self.valobj.target)
                        .GetValueAsUnsigned()
                    )

                    begin = (begin_hi << 64) | begin_lo
                    end = (end_hi << 64) | end_lo

                    # begin isn't necessarily smaller than end, so we must test for both cases
                    if begin < end:
                        if begin <= tag <= end:
                            self.variant = child
                            self.value = child.GetChildMemberWithName("value")
                        if (synth := self.value.GetSyntheticValue()).IsValid():
                            self.value = synth
                            return
                    else:
                        if tag >= begin or tag <= end:
                            self.variant = child
                            self.value = child.GetChildMemberWithName("value")
                        if (synth := self.value.GetSyntheticValue()).IsValid():
                            self.value = synth
                            return

    def num_children(self) -> int:
        return self.value.GetNumChildren()

    def get_child_index(self, name: str) -> int:
        return self.value.GetIndexOfChildWithName(name)

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        return self.value.GetChildAtIndex(index)

    def has_children(self) -> bool:
        return self.value.MightHaveChildren()

    def get_type_name(self) -> str:
        name = self.valobj.GetTypeName()
        # remove "enum2$<", str.removeprefix() is python 3.9+
        name = name[7:]

        # MSVC misinterprets ">>" as a shift operator, so spaces are inserted by rust to
        # avoid that
        if name.endswith(" >"):
            name = name[:-2]
        elif name.endswith(">"):
            name = name[:-1]

        return name


def MSVCEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    enum_synth = MSVCEnumSyntheticProvider(valobj.GetNonSyntheticValue(), _dict)
    variant_names: SBType = valobj.target.FindFirstType(
        f"{enum_synth.valobj.GetTypeName()}::VariantNames"
    )
    try:
        name_idx = (
            enum_synth.variant.GetType()
            .GetStaticFieldWithName("NAME")
            .GetConstantValue(valobj.target)
            .GetValueAsUnsigned()
        )
    except AttributeError:
        # LLDB versions prior to 19 do not have the `SBTypeGetStaticField` API, and have no way
        # to determine the value based on the tag field.
        tag: SBValue = valobj.GetChildMemberWithName("tag")

        if tag.IsValid():
            discr: int = tag.GetValueAsUnsigned()
            return "".join(["{tag = ", str(tag.unsigned), "}"])
        else:
            tag_lo: int = valobj.GetChildMemberWithName(
                "tag128_lo"
            ).GetValueAsUnsigned()
            tag_hi: int = valobj.GetChildMemberWithName(
                "tag128_hi"
            ).GetValueAsUnsigned()

            discr: int = (tag_hi << 64) | tag_lo

        return "".join(["{tag = ", str(discr), "}"])

    name: str = variant_names.enum_members[name_idx].name

    if enum_synth.num_children() == 0:
        return name

    child_name: str = enum_synth.value.GetChildAtIndex(0).name
    if child_name == "0" or child_name == "__0":
        # enum variant is a tuple struct
        return name + TupleSummaryProvider(enum_synth.value, _dict)
    else:
        # enum variant is a regular struct
        return name + StructSummaryProvider(enum_synth.value, _dict)


class TupleSyntheticProvider:
    """Pretty-printer for tuples and tuple enum variants"""

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_variant: bool = False):
        # logger = Logger.Logger()
        self.valobj = valobj
        self.is_variant = is_variant
        self.type = valobj.GetType()

        if is_variant:
            self.size = self.type.GetNumberOfFields() - 1
        else:
            self.size = self.type.GetNumberOfFields()

    def num_children(self) -> int:
        return self.size

    def get_child_index(self, name: str) -> int:
        if name.isdigit():
            return int(name)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if self.is_variant:
            field = self.type.GetFieldAtIndex(index + 1)
        else:
            field = self.type.GetFieldAtIndex(index)
        element = self.valobj.GetChildMemberWithName(field.name)
        return self.valobj.CreateValueFromData(
            str(index), element.GetData(), element.GetType()
        )

    def update(self):
        pass

    def has_children(self) -> bool:
        return True


class MSVCTupleSyntheticProvider:
    __slots__ = ["valobj"]

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj

    def num_children(self) -> int:
        return self.valobj.GetNumChildren()

    def get_child_index(self, name: str) -> int:
        return self.valobj.GetIndexOfChildWithName(name)

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        child: SBValue = self.valobj.GetChildAtIndex(index)
        offset = self.valobj.GetType().GetFieldAtIndex(index).byte_offset
        return self.valobj.CreateChildAtOffset(str(index), offset, child.GetType())

    def update(self):
        pass

    def has_children(self) -> bool:
        return self.valobj.MightHaveChildren()

    def get_type_name(self) -> str:
        name = self.valobj.GetTypeName()
        # remove "tuple$<" and ">", str.removeprefix and str.removesuffix require python 3.9+
        name = name[7:-1].strip()
        return "(" + name + ")"


class StdVecSyntheticProvider:
    """Pretty-printer for alloc::vec::Vec<T>

    struct Vec<T> { buf: RawVec<T>, len: usize }
    rust 1.75: struct RawVec<T> { ptr: Unique<T>, cap: usize, ... }
    rust 1.76: struct RawVec<T> { ptr: Unique<T>, cap: Cap(usize), ... }
    rust 1.31.1: struct Unique<T: ?Sized> { pointer: NonZero<*const T>, ... }
    rust 1.33.0: struct Unique<T: ?Sized> { pointer: *const T, ... }
    rust 1.62.0: struct Unique<T: ?Sized> { pointer: NonNull<T>, ... }
    struct NonZero<T>(T)
    struct NonNull<T> { pointer: *const T }
    """

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        # logger = Logger.Logger()
        # logger >> "[StdVecSyntheticProvider] for " + str(valobj.GetName())
        self.valobj = valobj
        self.element_type = None
        ptr_size = valobj.GetTarget().GetAddressByteSize() * 8
        self.no_hi_bit_max = 1 << (ptr_size - 1)
        self.update()

    def num_children(self) -> int:
        return self.length

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        start = self.data_ptr.GetValueAsUnsigned()
        address = start + index * self.element_type_size
        element = self.data_ptr.CreateValueFromAddress(
            "[%s]" % index, address, self.element_type
        )
        return element

    def update(self):
        buf: SBValue = self.valobj.GetChildMemberWithName("buf")
        self.data_ptr = unwrap_unique_or_non_null(
            buf.GetChildMemberWithName("inner").GetChildMemberWithName("ptr")
        )

        capacity: int = buf.GetChildMemberWithName("cap").GetValueAsUnsigned()

        if capacity >= self.no_hi_bit_max or self.data_ptr.GetValueAsUnsigned() == 0:
            self.capacity = 0
            self.length = 0
        else:
            self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()

        self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)

        if not self.element_type.IsValid():
            arg_name = next(get_template_args(self.valobj.GetTypeName()))

            self.element_type = resolve_msvc_template_arg(arg_name, self.valobj.target)

        self.element_type_size = self.element_type.GetByteSize()

    def has_children(self) -> bool:
        return True


class StdSliceSyntheticProvider:
    __slots__ = ["valobj", "length", "data_ptr", "element_type", "element_size"]

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        self.update()

    def num_children(self) -> int:
        return self.length

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        start = self.data_ptr.GetValueAsUnsigned()
        address = start + index * self.element_size
        element = self.data_ptr.CreateValueFromAddress(
            "[%s]" % index, address, self.element_type
        )
        return element

    def update(self):
        self.length = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
        self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr")

        self.element_type = self.data_ptr.GetType().GetPointeeType()
        self.element_size = self.element_type.GetByteSize()

    def has_children(self) -> bool:
        return True


class MSVCStdSliceSyntheticProvider(StdSliceSyntheticProvider):
    def get_type_name(self) -> str:
        name = self.valobj.GetTypeName()

        if name.startswith("ref_mut"):
            # remove "ref_mut$<slice2$<" and trailing "> >"
            name = name[17:-3]
            ref = "&mut "
        else:
            # remove "ref$<slice2$<" and trailing "> >"
            name = name[13:-3]
            ref = "&"

        return "".join([ref, "[", name, "]"])


def StdSliceSummaryProvider(valobj, dict):
    output = sequence_formatter("[", valobj, dict)
    output += "]"
    return output


class StdVecDequeSyntheticProvider:
    """Pretty-printer for alloc::collections::vec_deque::VecDeque<T>

    struct VecDeque<T> { head: WrappedIndex, len: usize, buf: RawVec<T> }
    """

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        # logger = Logger.Logger()
        # logger >> "[StdVecDequeSyntheticProvider] for " + str(valobj.GetName())
        self.valobj = valobj
        self.element_type = None
        self.update()

    def num_children(self) -> int:
        return self.size

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit() and int(index) < self.size:
            return int(index)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        start = self.data_ptr.GetValueAsUnsigned()
        address = start + ((index + self.head) % self.cap) * self.element_type_size
        element = self.data_ptr.CreateValueFromAddress(
            "[%s]" % index, address, self.element_type
        )
        return element

    def update(self):
        head = self.valobj.GetChildMemberWithName("head")
        # BACKCOMPAT: rust 1.95
        if head.GetType().num_fields == 1:
            head = head.GetChildAtIndex(0)
        self.head = head.GetValueAsUnsigned()
        self.size = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
        self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName(
            "inner"
        )
        cap = self.buf.GetChildMemberWithName("cap")
        if cap.GetType().num_fields == 1:
            cap = cap.GetChildAtIndex(0)
        self.cap = cap.GetValueAsUnsigned()

        self.data_ptr = unwrap_unique_or_non_null(
            self.buf.GetChildMemberWithName("ptr")
        )

        self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)

        if not self.element_type.IsValid():
            arg_name = next(get_template_args(self.valobj.GetTypeName()))

            self.element_type = resolve_msvc_template_arg(arg_name, self.valobj.target)

        self.element_type_size = self.element_type.GetByteSize()

    def has_children(self) -> bool:
        return True


# BACKCOMPAT: rust 1.35
class StdOldHashMapSyntheticProvider:
    """Pretty-printer for std::collections::hash::map::HashMap<K, V, S>

    struct HashMap<K, V, S> {..., table: RawTable<K, V>, ... }
    struct RawTable<K, V> { capacity_mask: usize, size: usize, hashes: TaggedHashUintPtr, ... }
    """

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, show_values: bool = True):
        self.valobj = valobj
        self.show_values = show_values
        self.update()

    def num_children(self) -> int:
        return self.size

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        # logger = Logger.Logger()
        start = self.data_ptr.GetValueAsUnsigned() & ~1

        # See `libstd/collections/hash/table.rs:raw_bucket_at
        hashes = self.hash_uint_size * self.capacity
        align = self.pair_type_size
        # See `libcore/alloc.rs:padding_needed_for`
        len_rounded_up = (
            (
                (((hashes + align) % self.modulo - 1) % self.modulo)
                & ~((align - 1) % self.modulo)
            )
            % self.modulo
            - hashes
        ) % self.modulo
        # len_rounded_up = ((hashes + align - 1) & ~(align - 1)) - hashes

        pairs_offset = hashes + len_rounded_up
        pairs_start = start + pairs_offset

        table_index = self.valid_indices[index]
        idx = table_index & self.capacity_mask
        address = pairs_start + idx * self.pair_type_size
        element = self.data_ptr.CreateValueFromAddress(
            "[%s]" % index, address, self.pair_type
        )
        if self.show_values:
            return element
        else:
            key = element.GetChildAtIndex(0)
            return self.valobj.CreateValueFromData(
                "[%s]" % index, key.GetData(), key.GetType()
            )

    def update(self):
        # logger = Logger.Logger()

        self.table = self.valobj.GetChildMemberWithName("table")  # type: SBValue
        self.size = self.table.GetChildMemberWithName("size").GetValueAsUnsigned()
        self.hashes = self.table.GetChildMemberWithName("hashes")
        self.hash_uint_type = self.hashes.GetType()
        self.hash_uint_size = self.hashes.GetType().GetByteSize()
        self.modulo = 2**self.hash_uint_size
        self.data_ptr = self.hashes.GetChildAtIndex(0).GetChildAtIndex(0)

        self.capacity_mask = self.table.GetChildMemberWithName(
            "capacity_mask"
        ).GetValueAsUnsigned()
        self.capacity = (self.capacity_mask + 1) % self.modulo

        marker = self.table.GetChildMemberWithName("marker").GetType()  # type: SBType
        self.pair_type = marker.template_args[0]
        self.pair_type_size = self.pair_type.GetByteSize()

        self.valid_indices = []
        for idx in range(self.capacity):
            address = self.data_ptr.GetValueAsUnsigned() + idx * self.hash_uint_size
            hash_uint = self.data_ptr.CreateValueFromAddress(
                "[%s]" % idx, address, self.hash_uint_type
            )
            hash_ptr = hash_uint.GetChildAtIndex(0).GetChildAtIndex(0)
            if hash_ptr.GetValueAsUnsigned() != 0:
                self.valid_indices.append(idx)

        # logger >> "Valid indices: {}".format(str(self.valid_indices))

    def has_children(self) -> bool:
        return True


class StdHashMapSyntheticProvider:
    """Pretty-printer for hashbrown's HashMap"""

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, show_values: bool = True):
        self.valobj = valobj
        self.show_values = show_values
        self.update()

    def num_children(self) -> int:
        return self.size

    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)
        else:
            return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        pairs_start = self.data_ptr.GetValueAsUnsigned()
        idx = self.valid_indices[index]
        if self.new_layout:
            idx = -(idx + 1)
        address = pairs_start + idx * self.pair_type_size
        element = self.data_ptr.CreateValueFromAddress(
            "[%s]" % index, address, self.pair_type
        )

        if self.show_values:
            return element
        else:
            key = element.GetChildAtIndex(0)
            return self.valobj.CreateValueFromData(
                "[%s]" % index, key.GetData(), key.GetType()
            )

    def update(self):
        table = self.table()
        inner_table = table.GetChildMemberWithName("table")

        capacity = (
            inner_table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1
        )
        ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0)

        self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned()

        self.pair_type = table.GetType().GetTemplateArgumentType(0)

        if not self.pair_type.IsValid():
            arg_name = next(get_template_args(table.GetTypeName()))

            self.pair_type = resolve_msvc_template_arg(arg_name, self.valobj.target)

        if self.pair_type.IsTypedefType():
            self.pair_type = self.pair_type.GetTypedefedType()
        self.pair_type_size = self.pair_type.GetByteSize()

        self.new_layout = not inner_table.GetChildMemberWithName("data").IsValid()
        if self.new_layout:
            self.data_ptr = ctrl.Cast(self.pair_type.GetPointerType())
        else:
            self.data_ptr = inner_table.GetChildMemberWithName("data").GetChildAtIndex(
                0
            )

        u8_type = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar)
        u8_type_size = (
            self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar).GetByteSize()
        )

        self.valid_indices = []
        for idx in range(capacity):
            address = ctrl.GetValueAsUnsigned() + idx * u8_type_size
            value = ctrl.CreateValueFromAddress(
                "ctrl[%s]" % idx, address, u8_type
            ).GetValueAsUnsigned()
            is_present = value & 128 == 0
            if is_present:
                self.valid_indices.append(idx)

    def table(self) -> SBValue:
        if self.show_values:
            hashbrown_hashmap = self.valobj.GetChildMemberWithName("base")
        else:
            # BACKCOMPAT: rust 1.47
            # HashSet wraps either std HashMap or hashbrown::HashSet, which both
            # wrap hashbrown::HashMap, so either way we "unwrap" twice.
            hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0)
        return hashbrown_hashmap.GetChildMemberWithName("table")

    def has_children(self) -> bool:
        return True


def StdRcSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    strong = valobj.GetChildMemberWithName("strong").GetValueAsUnsigned()
    weak = valobj.GetChildMemberWithName("weak").GetValueAsUnsigned()
    return "strong={}, weak={}".format(strong, weak)


class StdRcSyntheticProvider:
    """Pretty-printer for alloc::rc::Rc<T> and alloc::sync::Arc<T>

    struct Rc<T> { ptr: NonNull<RcInner<T>>, ... }
    rust 1.31.1: struct NonNull<T> { pointer: NonZero<*const T> }
    rust 1.33.0: struct NonNull<T> { pointer: *const T }
    struct NonZero<T>(T)
    struct RcInner<T> { strong: Cell<usize>, weak: Cell<usize>, value: T }

    struct Arc<T> { ptr: NonNull<ArcInner<T>>, ... }
    struct ArcInner<T> { strong: atomic::Atomic<usize>, weak: atomic::Atomic<usize>, data: T }
    """

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_atomic: bool = False):
        self.valobj = valobj

        self.ptr = unwrap_unique_or_non_null(self.valobj.GetChildMemberWithName("ptr"))

        self.value = self.ptr.GetChildMemberWithName("data" if is_atomic else "value")

        self.strong = unwrap_scalar_wrappers(self.ptr.GetChildMemberWithName("strong"))
        self.weak = unwrap_scalar_wrappers(self.ptr.GetChildMemberWithName("weak"))

        self.value_builder = ValueBuilder(valobj)

        self.update()

    def num_children(self) -> int:
        # Actually there are 3 children, but only the `value` should be shown as a child
        return 1

    def get_child_index(self, name: str) -> int:
        if name == "value":
            return 0
        if name == "strong":
            return 1
        if name == "weak":
            return 2
        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if index == 0:
            return self.value
        if index == 1:
            return self.value_builder.from_uint("strong", self.strong_count)
        if index == 2:
            return self.value_builder.from_uint("weak", self.weak_count)

        return None

    def update(self):
        self.strong_count = self.strong.GetValueAsUnsigned()
        self.weak_count = self.weak.GetValueAsUnsigned() - 1

    def has_children(self) -> bool:
        return True


class StdCellSyntheticProvider:
    """Pretty-printer for std::cell::Cell"""

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
        self.valobj = valobj
        self.value = valobj.GetChildMemberWithName("value").GetChildAtIndex(0)

    def num_children(self) -> int:
        return 1

    def get_child_index(self, name: str) -> int:
        if name == "value":
            return 0
        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if index == 0:
            return self.value
        return None

    def update(self):
        pass

    def has_children(self) -> bool:
        return True


def StdRefSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    borrow = valobj.GetChildMemberWithName("borrow").GetValueAsSigned()
    return (
        "borrow={}".format(borrow) if borrow >= 0 else "borrow_mut={}".format(-borrow)
    )


class StdRefSyntheticProvider:
    """Pretty-printer for std::cell::Ref, std::cell::RefMut, and std::cell::RefCell"""

    def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_cell: bool = False):
        self.valobj = valobj

        borrow = valobj.GetChildMemberWithName("borrow")
        value = valobj.GetChildMemberWithName("value")
        if is_cell:
            self.borrow = borrow.GetChildMemberWithName("value").GetChildMemberWithName(
                "value"
            )
            self.value = value.GetChildMemberWithName("value")
        else:
            self.borrow = (
                borrow.GetChildMemberWithName("borrow")
                .GetChildMemberWithName("value")
                .GetChildMemberWithName("value")
            )
            self.value = value.Dereference()

        self.value_builder = ValueBuilder(valobj)

        self.update()

    def num_children(self) -> int:
        # Actually there are 2 children, but only the `value` should be shown as a child
        return 1

    def get_child_index(self, name: str) -> int:
        if name == "value":
            return 0
        if name == "borrow":
            return 1
        return -1

    def get_child_at_index(self, index: int) -> Optional[SBValue]:
        if index == 0:
            return self.value
        if index == 1:
            return self.value_builder.from_int("borrow", self.borrow_count)
        return None

    def update(self):
        self.borrow_count = self.borrow.GetValueAsSigned()

    def has_children(self) -> bool:
        return True


def StdNonZeroNumberSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
    inner = valobj.GetChildAtIndex(0)
    inner_inner = inner.GetChildAtIndex(0)

    # FIXME: Avoid printing as character literal,
    #        see https://github.com/llvm/llvm-project/issues/65076.
    if inner_inner.GetTypeName() in ["char", "unsigned char"]:
        return str(inner_inner.GetValueAsSigned())
    else:
        return inner_inner.GetValue()
