001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.model.annotations;
007
008import static java.lang.annotation.ElementType.FIELD;
009import static java.lang.annotation.ElementType.METHOD;
010import static java.lang.annotation.RetentionPolicy.RUNTIME;
011
012import java.lang.annotation.Documented;
013import java.lang.annotation.Retention;
014import java.lang.annotation.Target;
015
016import edu.umd.cs.findbugs.annotations.NonNull;
017
018/**
019 * Identifies that the annotation target is a bound property that participates
020 * in a Metaschema choice.
021 * <p>
022 * A choice represents mutually exclusive alternatives in a Metaschema model.
023 * Fields with the same {@link #choiceId()} are part of the same choice and
024 * exactly one of them must be provided when the choice is required.
025 * <p>
026 * This is distinct from {@link BoundChoiceGroup}, which represents a
027 * polymorphic collection with a type discriminator.
028 * <p>
029 * <strong>Adjacency requirement:</strong> All fields with the same
030 * {@code choiceId} must be declared consecutively in the class, reflecting the
031 * Metaschema model where choice alternatives occupy the same position in the
032 * serialization order.
033 */
034@Documented
035@Retention(RUNTIME)
036@Target({ FIELD, METHOD })
037public @interface BoundChoice {
038  /**
039   * Identifies which choice this field belongs to.
040   * <p>
041   * Fields with the same choiceId are mutually exclusive alternatives. The
042   * choiceId must be unique within the containing assembly and consistent across
043   * all alternatives in the choice.
044   *
045   * @return the choice identifier
046   */
047  @NonNull
048  String choiceId();
049}