001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2026 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
012 * specific language governing permissions and limitations under the License.
013 */
014package org.microbean.assign;
015
016import java.util.List;
017
018import java.util.function.Predicate;
019
020import javax.lang.model.AnnotatedConstruct;
021
022import javax.lang.model.element.AnnotationMirror;
023import javax.lang.model.element.ExecutableElement;
024
025/**
026 * An interface whose implementations bear <dfn>semantically significant annotations</dfn>.
027 *
028 * <p><dfn>Semantically significant</dfn> annotations are included in hashcode and equality computations.</p>
029 *
030 * @param <T> the type of the annotated object
031 *
032 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
033 *
034 * @see org.microbean.construct.element.AnnotationMirrors#sameAnnotation(AnnotationMirror, AnnotationMirror,
035 * java.util.function.Predicate)
036 *
037 * @see org.microbean.construct.element.AnnotationMirrors#containsAll(java.util.Collection, java.util.Collection,
038 * java.util.function.Predicate)
039 *
040 * @see org.microbean.construct.element.AnnotationMirrors#hashCode(AnnotationMirror, java.util.function.Predicate)
041 */
042public interface Annotated<T> {
043
044  /**
045   * Returns a non-{@code null}, immutable, determinate {@link List} of <dfn>semantically significant</dfn> {@link
046   * AnnotationMirror}s.
047   *
048   * <p>These annotations supersede any annotations that might otherwise be available from objects returned by the
049   * {@link #annotated()} method.</p>
050   *
051   * @return a non-{@code null}, immutable, determinate {@link List} of <dfn>semantically significant</dfn> {@link
052   * AnnotationMirror}s.
053   */
054  public List<AnnotationMirror> annotations();
055
056  /**
057   * Returns the non-{@code null}, determinate, annotated object.
058   *
059   * @return the non-{@code null}, determinate, annotated object.
060   */
061  public T annotated();
062
063  /**
064   * A convenience method that returns a new {@link Annotated} implementation.
065   *
066   * @param <T> the type of {@link AnnotatedConstruct}
067   *
068   * @param ac a non-{@code null} {@link AnnotatedConstruct}
069   *
070   * @return a new, non-{@code null} {@link Annotated} implementation
071   *
072   * @exception NullPointerException if {@code ac} is {@code null}
073   *
074   * @see #of(AnnotatedConstruct, Predicate)
075   */
076  public static <T extends AnnotatedConstruct> Annotated<T> of(final T ac) {
077    return of(ac, null);
078  }
079
080  /**
081   * A convenience method that returns a new {@link Annotated} implementation.
082   *
083   * @param <T> the type of {@link AnnotatedConstruct}
084   *
085   * @param ac a non-{@code null} {@link AnnotatedConstruct}
086   *
087   * @param p a {@link Predicate} that returns {@code true} if a given {@link ExecutableElement}, representing an
088   * annotation element, is to be included in comparison operations; may be {@code null} in which case it is as if
089   * {@code e -> true} were supplied instead
090   *
091   * @return a new, non-{@code null} {@link Annotated} implementation
092   *
093   * @exception NullPointerException if {@code ac} is {@code null}
094   */
095  public static <T extends AnnotatedConstruct> Annotated<T> of(final T ac, final Predicate<? super ExecutableElement> p) {
096    return new CacheableAnnotatedConstruct<T>(ac, p);
097  }
098
099}