AnnotationDeclaration.java

package net.morimekta.providence.reflect.model;

import net.morimekta.providence.descriptor.PAnnotation;
import net.morimekta.providence.reflect.parser.ThriftToken;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.util.Objects;

/**
 * A single annotation declaration, as part of the annotation list.
 *
 * <pre>{@code
 * annotation  :== {tag} ('=' {value})?
 * annotations :== '(' {annotation} (',' {annotation})* ')'
 * }</pre>
 */
@Immutable
public class AnnotationDeclaration {
    private final ThriftToken tagToken;
    private final ThriftToken valueToken;

    public AnnotationDeclaration(@Nonnull ThriftToken tagToken,
                                 @Nullable ThriftToken valueToken) {
        this.tagToken = tagToken;
        this.valueToken = valueToken;
    }

    public PAnnotation getAnnotation() {
        return PAnnotation.forTag(tagToken.toString());
    }

    public String getTag() {
        return tagToken.toString();
    }

    public String getValue() {
        if (valueToken == null) return "";
        return valueToken.decodeString(false);
    }

    public ThriftToken getTagToken() {
        return tagToken;
    }

    public ThriftToken getValueToken() {
        return valueToken;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(tagToken.toString());
        if (valueToken != null) {
            builder.append(": ").append(valueToken);
        }
        return builder.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof AnnotationDeclaration)) return false;
        AnnotationDeclaration other = (AnnotationDeclaration) obj;
        return Objects.equals(tagToken.toString(), other.tagToken.toString()) &&
               (valueToken == null) == (other.valueToken == null) &&
               (valueToken != null && Objects.equals(valueToken.toString(), other.valueToken.toString()));
    }

    @Override
    public int hashCode() {
        return Objects.hash(getClass(), tagToken, valueToken);
    }
}