001package sting;
002
003import java.lang.annotation.Documented;
004import java.lang.annotation.ElementType;
005import java.lang.annotation.Retention;
006import java.lang.annotation.RetentionPolicy;
007import java.lang.annotation.Target;
008import javax.annotation.Nonnull;
009
010/**
011 * Annotation that indicates the class that provides the service.
012 * This is an integration meta-annotation rather than a component-defining Sting annotation.
013 *
014 * <p>The class that provides the service may be either a {@link Fragment}-annotated type or an
015 * {@link Injectable}-annotated type. This annotation is applied to another framework's annotation to
016 * simplify integration with Sting. Sting consults it when the framework annotation is applied to a
017 * type element that Sting attempts to include or discover.</p>
018 *
019 * <p>When used for explicit include aliasing, Sting resolves the framework-managed type in an
020 * {@link Injector#includes()} annotation parameter or a {@link Fragment#includes()} annotation
021 * parameter to the provider type. In this case, the resolved provider only needs to exist and be
022 * annotated with {@link Fragment} or {@link Injectable}. The provider does not need to publish the
023 * framework-managed type unless that type must later be resolved as a Sting service.</p>
024 *
025 * <p>When used for auto-discovery, Sting resolves an unresolved service request for the
026 * framework-managed type to the provider type. In this case, the resolved provider must be
027 * annotated with {@link Fragment} or {@link Injectable} and publish the framework-managed type
028 * using the default qualifier.</p>
029 *
030 * <p>Frameworks that synthesize Sting providers should remember that Sting only observes
031 * {@link Eager}, {@link Named}, and {@link Typed} on the resolved provider. Providers used only as
032 * explicit include aliases usually do not need to copy those annotations for the framework-managed
033 * type. Providers intended to support auto-discovery usually should copy them when they need Sting
034 * to treat the framework-managed type as published with those semantics. In practice this means
035 * copying the annotations onto the generated {@link Injectable} subtype, or onto the provider
036 * method declared by the generated {@link Fragment}, depending on the provider style.</p>
037 *
038 * <p>The presence of this annotation does not itself create a Sting binding; the resolved provider
039 * type is what Sting processes.</p>
040 *
041 * <p>It should be noted that Sting will attempt to use any annotation with this name and shape so
042 * that frameworks do not need a direct code dependency on Sting.</p>
043 */
044@Documented
045@Retention( RetentionPolicy.RUNTIME )
046@Target( ElementType.ANNOTATION_TYPE )
047public @interface StingProvider
048{
049  /**
050   * The name pattern of the class that provides the service.
051   * The name is relative to the reference type (See above for how to determine the reference type).
052   * The package is the same package as the reference type. The pattern can include constant string
053   * parts as well as the following replacements:
054   *
055   * <ul>
056   *   <li>
057   *     <b>[SimpleName]</b>: The simple name of the class. i.e. For a top-level class like
058   *     {@code come.example.MyElement} the simple name is {@code "MyElement"}. For a nested class like
059   *     {@code come.example.MyElement.ElementType.Kind} the simple name is {@code "Kind"}.
060   *   </li>
061   *   <li>
062   *     <b>[CompoundName]</b>: The compound name of the class. i.e. For a top-level class like
063   *     {@code come.example.MyElement} the compound name is {@code "MyElement"}. For a nested class like
064   *     {@code come.example.MyElement.ElementType.Kind} the simple name is {@code "MyElement.ElementType.Kind"}.
065   *   </li>
066   *   <li>
067   *     <b>[EnclosingName]</b>: The compound name of the class with the simple name elided. i.e. For a top-level
068   *     class like {@code come.example.MyElement} the enclosing name is {@code ""}. For a nested class like
069   *     {@code come.example.MyElement.ElementType.Kind} the enclosing name is {@code "MyElement.ElementType."}.
070   *   </li>
071   *   <li>
072   *     <b>[FlatEnclosingName]</b>: The enclosing name of the class with the dots replaced with underscores.
073   *     i.e. For a top-level class like {@code come.example.MyElement} the flat enclosing name is {@code ""}.
074   *     For a nested class like {@code come.example.MyElement.ElementType.Kind} the flat enclosing name is
075   *     {@code "MyElement_ElementType_"}.
076   *   </li>
077   * </ul>
078   *
079   * <p>A typical pattern used by a framework such as <a href="https://arez.github.io/">Arez</a> is
080   * "[FlatEnclosingName]Arez_[SimpleName]"..</p>
081   *
082   * @return the pattern to produce a name.
083   */
084  @Nonnull
085  String value();
086}