# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# pyformat: disable

"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from typing import Any

from pydantic import BaseModel, TypeAdapter, ValidationError
from .serializers import construct_unvalidated


def parse_open_union(
    v: Any,
    *,
    disc_key: str,
    variants: dict[str, Any],
    unknown_cls: type,
    union_name: str,
    lenient: bool = False,
) -> Any:
    """Parse an open discriminated union value with forward-compatibility.

    Known discriminator values are dispatched to their variant types.
    Unknown discriminator values — or known discriminator values whose
    payload fails variant validation (e.g. a partial variant emitted by a
    newer server) — produce an instance of the fallback class, preserving
    the raw payload for inspection.

    Non-dict values and dicts missing the discriminator deliberately raise
    instead of falling back, so pydantic can try sibling branches of an
    enclosing union (e.g. None in Optional[...]).
    """
    if isinstance(v, BaseModel):
        return v
    if not isinstance(v, dict) or disc_key not in v:
        raise ValueError(f"{union_name}: expected object with '{disc_key}' field")
    disc = v[disc_key]
    variant_cls = variants.get(disc)
    if variant_cls is not None:
        try:
            if isinstance(variant_cls, type) and issubclass(variant_cls, BaseModel):
                return variant_cls.model_validate(v)
            return TypeAdapter(variant_cls).validate_python(v)
        except ValidationError:
            if lenient:
                try:
                    return construct_unvalidated(v, variant_cls)
                except Exception:
                    pass
            return unknown_cls(raw=v)
    return unknown_cls(raw=v)
