# AbstractC4Rule.java

    package org.thewonderlemming.c4plantuml.linter.rules.builtin;

    import java.util.Optional;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;

    import org.antlr.v4.runtime.Parser;
    import org.antlr.v4.runtime.tree.ParseTree;
    import org.thewonderlemming.c4plantuml.grammars.SourceType;
    import org.thewonderlemming.c4plantuml.grammars.generated.C4L1Parser;
    import org.thewonderlemming.c4plantuml.grammars.generated.C4L2Parser;
    import org.thewonderlemming.c4plantuml.grammars.generated.C4L3Parser;
    import org.thewonderlemming.c4plantuml.linter.rules.AbstractLintingRule;
    import org.thewonderlemming.c4plantuml.linter.rules.RuleParameters;

    /**
     * A base implementation of {@link AbstractLintingRule} that provides default support for C4 levels 1 to 3.
     *
     * @author thewonderlemming
     *
     */
    public abstract class AbstractC4Rule extends AbstractLintingRule {

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

        @Override
        public Set<Class<? extends Parser>> acceptableParsersTypes() {

            return Stream
                .of(SourceType.C4_L1, SourceType.C4_L2, SourceType.C4_L3)
                    .map(SourceType::getParserType)
                    .collect(Collectors.toSet());
        }

        @Override
        public Optional<ParseTree> selectParseTree(final Parser parser) {

            final ParseTree tree;

            if (parser instanceof C4L1Parser) {
                tree = ((C4L1Parser) parser).diagram();

            } else if (parser instanceof C4L2Parser) {
                tree = ((C4L2Parser) parser).diagram();

            } else if (parser instanceof C4L3Parser) {
                tree = ((C4L3Parser) parser).diagram();

            } else {
                getLogger().error("Unsupported parser type {} was given", parser.getClass());
                return Optional.empty();
            }

            return Optional.of(tree);
        }

        @Override
        public void wrapUp() {
            // Override this if you want to add custom behavior at the end of a file
            // parsing.
        }
    }