/*
 * Copyright 2020, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.server.tuple;

import com.google.protobuf.Message;
import io.spine.server.tuple.Element.AValue;
import io.spine.server.tuple.Element.BValue;
import io.spine.server.tuple.Element.CValue;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * A value which can be one of three possible types.
 *
 * @param <A> the type of the first alternative
 * @param <B> the type of the second alternative
 * @param <C> the type of the third alternative
 */
public final class EitherOf3<A extends Message, B extends Message, C extends Message>
    extends Either
    implements AValue<A>, BValue<B>, CValue<C> {

    private static final long serialVersionUID = 0L;

    private EitherOf3(Message value, int index) {
        super(value, index);
    }

    /**
     * Creates a new instance with {@code <A>} value.
     */
    public static <A extends Message, B extends Message, C extends Message>
    EitherOf3<A, B, C> withA(A a) {
        checkNotNull(a);
        EitherOf3<A, B, C> result = new EitherOf3<>(a, 0);
        return result;
    }

    /**
     * Creates a new instance with {@code <B>} value.
     */
    public static <A extends Message, B extends Message, C extends Message>
    EitherOf3<A, B, C> withB(B b) {
        checkNotNull(b);
        EitherOf3<A, B, C> result = new EitherOf3<>(b, 1);
        return result;
    }

    /**
     * Creates a new instance with {@code <C>} value.
     */
    public static <A extends Message, B extends Message, C extends Message>
    EitherOf3<A, B, C> withC(C c) {
        checkNotNull(c);
        EitherOf3<A, B, C> result = new EitherOf3<>(c, 2);
        return result;
    }

    /**
     * Obtains the value of the first alternative.
     *
     * @throws IllegalStateException if a value of another type is stored instead.
     * @return the stored value
     * @see #hasA()
     */
    @Override
    public A getA() {
        return get(this, 0);
    }

    /**
     * Tells whether {@code <A>} value is stored.
     *
     * @return {@code true} if the first alternative value is set, {@code false} otherwise
     */
    @Override
    public boolean hasA() {
        return index() == 0;
    }

    /**
     * Obtains the value of the second alternative.
     *
     * @throws IllegalStateException if a value of another type is stored instead.
     * @return the stored value
     */
    @Override
    public B getB() {
        return get(this, 1);
    }

    /**
     * Tells whether {@code <B>} value is stored.
     *
     * @return {@code true} if the second alternative value is set, {@code false} otherwise
     */
    @Override
    public boolean hasB() {
        return index() == 1;
    }

    /**
     * Obtains the value of the third alternative.
     *
     * @throws IllegalStateException if a value of another type is stored instead.
     * @return the stored value
     * @see #hasC()
     */
    @Override
    public C getC() {
        return get(this, 2);
    }

    /**
     * Tells whether {@code <C>} value is stored.
     *
     * @return {@code true} if the third alternative value is set, {@code false} otherwise
     */
    @Override
    public boolean hasC() {
        return index() == 2;
    }
}

@@ -3369,24 +3369,44 @@
 tored value%0A
+     * @see #hasB()%0A
      */%0A    

Add a missing bit to the documentation.