AbstractLintingRule.java

package org.thewonderlemming.c4plantuml.linter.rules;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thewonderlemming.c4plantuml.commons.Reporter;
import org.thewonderlemming.c4plantuml.linter.SyntaxError;

/**
 * Represents a linting rule and exposes the methods to be implemented/customized by concrete linting rules.
 *
 * @author thewonderlemming
 *
 */
public abstract class AbstractLintingRule {

    private final RuleParameters parameters;

    private final List<SyntaxError> syntaxErrors = new ArrayList<>();


    /**
     * Default constructor.
     *
     * @param parameters the {@link RuleParameters} to pass to control the behavior of the rule.
     */
    protected AbstractLintingRule(final RuleParameters parameters) {
        this.parameters = parameters;
    }

    /**
     * Returns a list of supported ANTLR4 {@link Parser}.
     *
     * @return the list of supported {@link Parser}.
     */
    public abstract Set<Class<? extends Parser>> acceptableParsersTypes();

    /**
     * Returns a {@link ParseTreeListener} given a {@link Parser} type.
     * <p>
     * The {@link Reporter} can be passed at the {@link ParseTreeListener} if needed.
     *
     * @param reporter the {@link Reporter} to pass to the new {@link ParseTreeListener}.
     * @param parserType the {@link Parser} for the current C4 grammar.
     * @return the {@link ParseTreeListener} that matches the {@link Parser} grammar.
     */
    public abstract Optional<? extends ParseTreeListener> createParseTreeListener(final Reporter reporter,
        final Class<? extends Parser> parserType);

    /**
     * Returns the logger to be used within custom {@link AbstractLintingRule}.
     *
     * @return the logger to be used within the rules.
     */
    public final Logger getLogger() {
        return LoggerFactory.getLogger(getClass().getName());
    }

    /**
     * Returns a list of reported {@link SyntaxError}.
     *
     * @return a list of {@link SyntaxError}.
     */
    public List<SyntaxError> getSyntaxErrors() {
        return Collections.unmodifiableList(this.syntaxErrors);
    }

    /**
     * Collects a new {@link SyntaxError}.
     *
     * @param parseError the {@link SyntaxError} to report.
     */
    public final void reportSyntaxError(final SyntaxError parseError) {
        this.syntaxErrors.add(parseError);
    }

    /**
     * Selects a {@link ParseTree} to process, given a {@link Parser} grammar.
     *
     * @param parser the {@link Parser} instance to parse the current grammar.
     * @return the {@link ParseTree} that matches the current grammar.
     */
    public abstract Optional<ParseTree> selectParseTree(final Parser parser);

    /**
     * A call that takes place after the parsing process of a file.
     * <p>
     * Implements that call if you need post processing at the end of the linting operation.
     */
    public abstract void wrapUp();

    /**
     * Clears the reported {@link SyntaxError} within the rule.
     */
    protected final void clearSyntaxErrors() {
        this.syntaxErrors.clear();
    }

    /**
     * Returns the current {@link AbstractLintingRule} parameters.
     *
     * @return the rule {@link RuleParameters}.
     */
    protected final RuleParameters getParameters() {
        return this.parameters;
    }
}