<?xml version="1.0" encoding="UTF-8"?>

<document xmlns="http://maven.apache.org/XDOC/2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

  <head>
    <title>Writing Javadoc Checks</title>
    <script type="text/javascript"
            src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"/>
    <script type="text/javascript" src="js/anchors.js"/>
    <script type="text/javascript" src="js/google-analytics.js"/>
    <link rel="icon" href="images/favicon.png" type="image/x-icon" />
    <link rel="shortcut icon" href="images/favicon.ico" type="image/ico" />
  </head>

  <body>
    <section name="Content">
      <macro name="toc">
        <param name="fromDepth" value="1"/>
        <param name="toDepth" value="1"/>
      </macro>
    </section>

    <section name="What is Javadoc comment">
      <p>
      Javadoc comment is a multiline comment <code>/*  */</code> that starts with the <b>*</b>
      character and placed above the class definition, interface definition, enum definition,
      method definition or field definition.
      If an annotation precedes any of the definitions listed above, then the javadoc comment
      should be placed before the annotation.
      If several multiline comments with javadoc identifiers are placed sequentially, only
      the one closest to the definition, right above it, with the javadoc identifier will be used.
      </p>
      <p>
      Javadoc comments should contain: a short summary (the first sentence), an optional
      documentation section, an optional tag section.
      The first sentence has a special meaning and should be clear, punchy, short, and is ended by
      a period symbol.
      Immediately after the first sentence, the main description could begin, which may be followed
      by the tag section.
      The tag section starts with the first block tag, which is defined by the first <code>@</code>
      character that begins a line (ignoring leading asterisks, white space, and leading separator
      <code>/**</code>).
      </p>
      <p>For example, here is java file:</p>
      <source><![CDATA[
/**
 * My <b>class</b>.
 *
 * @see Annotation
 */
public class MyClass {

  /** Not a javadoc (ignored). */

  /**
   * Doubles the value.
   * The long and detailed explanation what the method does.
   *
   * @param value for doubling.
   * @return double value.
   */

  /*
   Multiline comment (ignored).
  */
  @Annotation
  /** Extra javadoc (ignored). */
  // Single line comment (ignored).
  public int method(int value) {
    /** Inner javadoc (ignored). */
    return value * 2;
  }
}
      ]]></source>
      <p>Javadoc content for the MyClass will be:</p>
      <source><![CDATA[
    My <b>class</b>.

    @see Annotation
      ]]></source>
      <p>Javadoc content for the MyClass.method will be:</p>
      <source><![CDATA[
    Doubles the value.
    The long and detailed explanation what the method does.

    @param value for doubling.
    @return double value.
      ]]></source>
      <p>
      Attention that java comment starts with <code>/*</code>, following with Identifier of
      comment type. Javadoc Identifier is <code>*</code>. All symbols after Javadoc
      Identifier till <code>*/</code> are part of javadoc comment.
      </p>
      <p>Please note that javadoc-like (multiline comment with javadoc identifier) comment inside
      a method is not a javadoc comment and skipped by Sun/Oracle javadoc tool and by our javadoc
      comment matcher, but such comment will be in AST.
      </p>
      <p>You can find different types of documentation generation tools similar to javadoc on the
      Internet. Such tools rely on specific Identifier: "!", "#", "$".
      Comments look like <code>"/*! some comment */"</code> , <code>"/*# some comment */"</code> ,
      <code>"/*$ some comment */"</code>. Such multiline comments are not a javadoc.
      </p>
    </section>

    <section name="Limitations">
      <p>
      Javadoc by specification could contain any HTML tags that let user generate content he needs.
      All tags are copied as is to result javadoc html pages by Sun/Oracle javadoc tool.
      All bad formatting is responsibility of user and web-browser. To validate Checkstyle to parse
      input to predictable structure - Abstract Syntax Tree(AST). It is very difficult to parse
      free style format, so input text need to follow some format, so limitation appears.
      </p>
      <p>
      The comment should be written in <a href="#Tight-HTML_rules">Tight-HTML</a>
          to build nested AST Tree that most Checks expect.
      </p>
      <p>
        For more details about parsing of HTML into AST read
          <a href="#HTML_Code_In_Javadoc_Comments">HTML Code In Javadoc Comments</a>
          and <a href="#Javadoc_parser_behavior_for_current_HTML_version_and_new_HTML_version">
          Javadoc parser behavior
        </a>  section.
      </p>
    </section>

    <section name="Tight-HTML rules">
      <p>
      Every HTML tag should have matching end HTML tag or it is a
          <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void element</a>.
      </p>
      <p>
      The only exceptions are HTML 4 tags whose end tag is optional (omittable) by
      HTML specification (example is
      <a href="https://www.w3.org/TR/html5/tabular-data.html#the-tr-element">TR</a>), so,
      Checkstyle won't show error about missing end tag, however,
      it leads to broken Tight-HTML structure and as a result
      leads to not-nested content of the HTML tags in Abstract Syntax Tree of the Javadoc comment.
      <br/>
      In other words, if HTML tags are not closed Javadoc grammar cannot determine content
      of these tags, so structure of the parse tree will not be nested like it is while using
      <a href="#Tight-HTML_rules">Tight-HTML</a> code. It is done just to not fail on every
      Javadoc comment, because there are tons of using unclosed tags, etc.
      </p>
      <p>
      Other rules:
      </p>
      <ul>
        <li>Document Structure elements (DOCTYPE, &lt;html&gt;, &lt;body&gt;, etc) are
            not mandatory.</li>
        <li>Elements must always be closed, except HTML4 elements whose end tag is optional
            (omittable) and HTML4
            <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void elements</a>.
            See <a href="#HTML_Code_In_Javadoc_Comments">HTML Code In Javadoc Comments</a>
            section</li>
        <li>HTML elements can be either in lowercase or in uppercase</li>
        <li>Attribute names can be either in lowercase or in uppercase</li>
        <li>Attribute values can be either quoted or not be quoted</li>
      </ul>
    </section>

    <section name="How to create Javadoc Check">
      <p>
        Principle of writing Javadoc Checks is similar to writing regular Checks. You just extend
        another abstract class and use another token types.
      </p>
      <p>
      To start implementing new Check create a new class and extend <a
      href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html">
          AbstractJavadocCheck</a>.
      It has two abstract methods you should implement:
      </p>
      <ul>
        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">
              getDefaultJavadocTokens()</a> - return int array of
          javadoc token types your Check is going to process.
          The array should contain int constants from
          <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html">
          JavadocTokenTypes</a> class. (There is also
            <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html">
                TokenTypes</a> class in Checkstyle. Make sure you use
          <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html">
              JavadocTokenTypes</a> class in your Check, because the
          <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html">
              TokenTypes</a> is used to describe standard Java
          <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">
              DetailAST</a> token type.)
        </li>
        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#visitJavadocToken-com.puppycrawl.tools.checkstyle.api.DetailNode-">
          visitJavadocToken(DetailNode)</a> - it's a place you should put tree nodes processing.
          The argument is Javadoc tree node of type you described before in
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">
              getDefaultJavadocTokens()</a> method.
        </li>
      </ul>
    </section>

    <section name="Difference between Java Grammar and Javadoc comments Grammar">
      <p>
        Java grammar parses java file base on Java language specifications. So, there are
        singleline comments and multiline/block comments in it.
        Java compiler doesn't know about Javadoc because it is just a multiline comment.
        To parse multiline comment as a Javadoc comment, checkstyle has special Parser
        that is based on ANTLR Javadoc grammar. So, it's supposed to process block comments
        that start with Javadoc Identifier and parse them to Abstract Syntax Tree (AST).
      </p>
      <p>
        The difference is that Java grammar uses ANTLR v2, while Javadoc grammar uses ANTLR v4.
        Because of that, these two grammars and their trees are not compatible.
        Java AST consists of
        <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a>
        objects, while Javadoc AST consists of
        <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailNode.html">DetailNode</a>
        objects.
      </p>
      <p>
        Main Java grammar skips any whitespaces and newlines, so in Java Abstract Syntax Tree there
        are no whitespace/newline nodes. In Javadoc comment every whitespace matters, and Javadoc
        Checks need all those whitespaces and newline nodes to verify format and content of the
        Javadoc comment. Because of that Javadoc grammar includes all whitespaces, newlines to
        the parse tree
        (<a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#WS">WS</a>,
        <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#NEWLINE">
            NEWLINE</a>).
      </p>
    </section>

    <section name="Tool to print Javadoc tree structure">
      <p>
      Checkstyle can print Abstract Syntax Tree for Java and Javadoc trees. You need to run
      checkstyle jar file with <b>-J</b> argument, providing java file.
      </p>
      <p>For example, here is MyClass.java file:</p>
      <source><![CDATA[
/**
 * My <b>class</b>.
 * @see AbstractClass
 */
public class MyClass {

}
      ]]></source>
      <p>Command:</p>
      <div class="wrap-content">
        <source>
          java -jar checkstyle-X.XX-all.jar -J MyClass.java
        </source>
      </div>
      <p>Output:</p>
      <source><![CDATA[
CLASS_DEF -> CLASS_DEF [5:0]
|--MODIFIERS -> MODIFIERS [5:0]
|   |--BLOCK_COMMENT_BEGIN -> /* [1:0]
|   |   |--COMMENT_CONTENT -> *\n * My <b>class</b>.\n * @see AbstractClass\n  [1:2]
|   |   |   `--JAVADOC -> JAVADOC [1:3]
|   |   |       |--NEWLINE -> \n [1:3]
|   |   |       |--LEADING_ASTERISK ->  * [2:0]
|   |   |       |--TEXT ->  My  [2:2]
|   |   |       |--HTML_ELEMENT -> HTML_ELEMENT [2:6]
|   |   |       |   `--HTML_TAG -> HTML_TAG [2:6]
|   |   |       |       |--HTML_ELEMENT_START -> HTML_ELEMENT_START [2:6]
|   |   |       |       |   |--START -> < [2:6]
|   |   |       |       |   |--HTML_TAG_NAME -> b [2:7]
|   |   |       |       |   `--END -> > [2:8]
|   |   |       |       |--TEXT -> class [2:9]
|   |   |       |       `--HTML_ELEMENT_END -> HTML_ELEMENT_END [2:14]
|   |   |       |           |--START -> < [2:14]
|   |   |       |           |--SLASH -> / [2:15]
|   |   |       |           |--HTML_TAG_NAME -> b [2:16]
|   |   |       |           `--END -> > [2:17]
|   |   |       |--TEXT -> . [2:18]
|   |   |       |--NEWLINE -> \n [2:19]
|   |   |       |--LEADING_ASTERISK ->  * [3:0]
|   |   |       |--WS ->   [3:2]
|   |   |       |--JAVADOC_TAG -> JAVADOC_TAG [3:3]
|   |   |       |   |--SEE_LITERAL -> @see [3:3]
|   |   |       |   |--WS ->   [3:7]
|   |   |       |   |--REFERENCE -> REFERENCE [3:8]
|   |   |       |   |   `--CLASS -> AbstractClass [3:8]
|   |   |       |   |--NEWLINE -> \n [3:21]
|   |   |       |   `--WS ->   [4:0]
|   |   |       `--EOF -> <EOF> [4:1]
|   |   `--BLOCK_COMMENT_END -> */ [4:1]
|   `--LITERAL_PUBLIC -> public [5:0]
|--LITERAL_CLASS -> class [5:7]
|--IDENT -> MyClass [5:13]
`--OBJBLOCK -> OBJBLOCK [5:21]
    |--LCURLY -> { [5:21]
    `--RCURLY -> } [7:0]
      ]]></source>
      <p>
        As you see very small java file transforms to a huge Abstract Syntax Tree, because that is
        the most detailed tree including all components of the java file: classes, methods,
        comments, etc.
      </p>
      <p>
        In most cases while developing Javadoc Check, you need to only parse the tree of the exact
        Javadoc comment. To do that just copy Javadoc comment to separate file and remove <b>/**</b>
        at the beginning and <b>*/</b> at the end. After that, run checkstyle with <b>-j</b>
        argument.
      </p>
      <p>MyJavadocComment.javadoc file:</p>
      <source><![CDATA[
 * My <b>class</b>.
 * @see AbstractClass
      ]]></source>
      <p>Command:</p>
      <div class="wrap-content">
        <source>
          java -jar checkstyle-X.XX-all.jar \
          &#xa0;&#xa0;&#xa0;&#xa0;-j MyJavadocComment.javadoc
        </source>
      </div>
      <p>Output:</p>
      <source><![CDATA[
JAVADOC -> JAVADOC [0:0]
|--LEADING_ASTERISK ->  * [0:0]
|--TEXT ->  My  [0:2]
|--HTML_ELEMENT -> HTML_ELEMENT [0:6]
|   `--HTML_TAG -> HTML_TAG [0:6]
|       |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:6]
|       |   |--START -> < [0:6]
|       |   |--HTML_TAG_NAME -> b [0:7]
|       |   `--END -> > [0:8]
|       |--TEXT -> class [0:9]
|       `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:14]
|           |--START -> < [0:14]
|           |--SLASH -> / [0:15]
|           |--HTML_TAG_NAME -> b [0:16]
|           `--END -> > [0:17]
|--TEXT -> . [0:18]
|--NEWLINE -> \n [0:19]
|--LEADING_ASTERISK ->  * [1:0]
|--WS ->   [1:2]
|--JAVADOC_TAG -> JAVADOC_TAG [1:3]
|   |--SEE_LITERAL -> @see [1:3]
|   |--WS ->   [1:7]
|   `--REFERENCE -> REFERENCE [1:8]
|       `--CLASS -> AbstractClass [1:8]
`--EOF -> <EOF> [1:21]
      ]]></source>
    </section>

    <section name="Access Java AST from Javadoc Check">
      <p>
      As you already know Javadoc parse tree is a result of parsing block comment. There is a
      method to get the original block comment from Javadoc Check.
      You may need this block comment to check its position or something else in java
      <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> tree.
      </p>
      <p>
      For example, to write a JavadocCheck that verifies @param tags in Javadoc comment of
      a method definition, you also need all method's parameter names. To get method
      definition AST you should access java
      <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> tree
      from javadoc Check. For this purpose use
      <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getBlockCommentAst--">
          getBlockCommentAst()</a>
      method that returns
      <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> node.
      </p>
      <p>
        Example:
      </p>
      <source>
class MyCheck extends AbstractJavadocCheck {

    @Override
    public int[] getDefaultJavadocTokens() {
        return new int[]{JavadocTokenTypes.PARAMETER_NAME};
    }

    @Override
    public void visitJavadocToken(DetailNode paramNameNode) {
        String javadocParamName = paramNameNode.getText();
        DetailAST blockCommentAst = getBlockCommentAst();

        if (BlockCommentPosition.isOnMethod(blockCommentAst)) {

            DetailAST methodDef = blockCommentAst.getParent();
            DetailAST methodParam = findMethodParameter(methodDef);
            String methodParamName = methodParam.getText();

            if (!javadocParamName.equals(methodParamName)) {
                log(methodParam, "params.dont.match");
            }

        }
    }
}
      </source>
    </section>

    <section name="HTML Code In Javadoc Comments">
      <p>
        Checkstyle supports HTML4 tags in Javadoc comments:
          <a href="https://www.w3.org/TR/html4/index/elements.html">
          all HTML4 elements</a>.
      </p>
      <p>
        HTML4 is picked just to have a list of elements whose end tag is optional(omittable) and a
        list of <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void elements</a>
        (also known as <a href="https://www.w3schools.com/html/html_elements.asp">empty html
        tags</a>, for example <a href="https://www.w3.org/TR/html4/struct/text.html#edef-BR">BR
        tag</a>).
      </p>
      <p>
        HTML4 elements whose end tag is optional (omittable): &lt;P&gt;, &lt;LI&gt;, &lt;TR&gt;,
        &lt;TD&gt;, &lt;TH&gt;, &lt;BODY&gt;, &lt;COLGROUP&gt;, &lt;DD&gt;, &lt;DT&gt;,
        &lt;HEAD&gt;, &lt;HTML&gt;, &lt;OPTION&gt;, &lt;TBODY&gt;, &lt;THEAD&gt;, &lt;TFOOT&gt;.
      </p>
      <p>
        Void HTML4 elements: &lt;AREA&gt;, &lt;BASE&gt;, &lt;BASEFONT&gt;, &lt;BR&gt;, &lt;COL&gt;,
        &lt;FRAME&gt;, &lt;HR&gt;, &lt;IMG&gt;, &lt;INPUT&gt;, &lt;ISINDEX&gt;, &lt;LINK&gt;,
        &lt;META&gt;, &lt;PARAM&gt;.
      </p>

      <p>
        To make Checkstyle support HTML5 tags whose end tag is optional (omittable) and HTML5 void
        elements we should update Javadoc Parser because each element that breaks
        <a href="#Tight-HTML_rules">Tight-HTML rules</a> have to be defined in Javadoc grammar.
        In future we should update Javadoc grammar if those tag lists extend (new tags, new HTML
        standard, etc.).
        (We already have an <a href='https://github.com/checkstyle/checkstyle/issues/3332'>issue
        on updating Javadoc grammar to HTML5</a>)
      </p>

      <p>
        If Checkstyle meets unknown tag (for example HTML5 tag)
        it doesn't fail and parses this tag as
        <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#HTML_TAG">
            HTML_TAG</a>
          Javadoc token type.
        Just follow <a href="#Tight-HTML_rules">Tight-HTML rules</a> to make
          Checkstyle javadoc parser make nested AST, even though tags are unknown.

        <source><![CDATA[
<audio><source src="horse.ogg" type="audio/ogg"/></audio>
        ]]></source>

        <source><![CDATA[
JAVADOC -> JAVADOC [0:0]
|--HTML_ELEMENT -> HTML_ELEMENT [0:0]
|   `--HTML_TAG -> HTML_TAG [0:0]
|       |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:0]
|       |   |--START -> < [0:0]
|       |   |--HTML_TAG_NAME -> audio [0:1]
|       |   `--END -> > [0:6]
|       |--HTML_ELEMENT -> HTML_ELEMENT [0:7]
|       |   `--SINGLETON_ELEMENT -> SINGLETON_ELEMENT [0:7]
|       |       `--EMPTY_TAG -> EMPTY_TAG [0:7]
|       |           |--START -> < [0:7]
|       |           |--HTML_TAG_NAME -> source [0:8]
|       |           |--WS ->   [0:14]
|       |           |--ATTRIBUTE -> ATTRIBUTE [0:15]
|       |           |   |--HTML_TAG_NAME -> src [0:15]
|       |           |   |--EQUALS -> = [0:18]
|       |           |   `--ATTR_VALUE -> "horse.ogg" [0:19]
|       |           |--WS ->   [0:31]
|       |           |--ATTRIBUTE -> ATTRIBUTE [0:32]
|       |           |   |--HTML_TAG_NAME -> type [0:32]
|       |           |   |--EQUALS -> = [0:36]
|       |           |   `--ATTR_VALUE -> "audio/ogg" [0:37]
|       |           `--SLASH_END -> /> [0:49]
|       `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:51]
|           |--START -> < [0:51]
|           |--SLASH -> / [0:52]
|           |--HTML_TAG_NAME -> audio [0:53]
|           `--END -> > [0:58]
`--EOF -> <EOF> [0:59]
        ]]></source>
      </p>

    <p>
      Here is what you get if unknown tag doesn't have matching end tag (for example, HTML5 tag
      &lt;audio&gt;): <br/>
      Input:
      <source>&lt;audio&gt;test</source>
      Output:
    </p>
    <div class="wrap-content">
      <source>
        [ERROR:0] Javadoc comment at column 1 has parse error. Missed HTML close tag 'audio'.
        Sometimes it means that close tag missed for one of previous tags.
      </source>
    </div>
    <p>
      As you see Javadoc parser prints error and doesn't build AST if unknown HTML tag doesn't
      have matching end tag. If that a case please create an issue against Checkstyle to
      upgrade parser.
    </p>

    <p>
      There are also HTML tags that are marked as "Not supported in HTML5"
        (<a href='https://www.w3schools.com/tags/default.asp'>HTML Element Reference</a>).
      Checkstyle Javadoc parser can parse those tags too if they are written in
        <a href="#Tight-HTML_rules">Tight-HTML</a>.
      <br/>
      Example.
      <br/>
      Input:
      <source><![CDATA[
<acronym title="as soon as possible">ASAP</acronym>
      ]]></source>
      <br/>
      Output:
      <source><![CDATA[
JAVADOC -> JAVADOC [0:0]
|--HTML_ELEMENT -> HTML_ELEMENT [0:0]
|   `--HTML_TAG -> HTML_TAG [0:0]
|       |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:0]
|       |   |--START -> < [0:0]
|       |   |--HTML_TAG_NAME -> acronym [0:1]
|       |   |--WS ->   [0:8]
|       |   |--ATTRIBUTE -> ATTRIBUTE [0:9]
|       |   |   |--HTML_TAG_NAME -> title [0:9]
|       |   |   |--EQUALS -> = [0:14]
|       |   |   `--ATTR_VALUE -> "as soon as possible" [0:15]
|       |   `--END -> > [0:37]
|       |--TEXT -> ASAP [0:38]
|       `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:42]
|           |--START -> < [0:42]
|           |--SLASH -> / [0:43]
|           |--HTML_TAG_NAME -> acronym [0:44]
|           `--END -> > [0:51]
`--EOF -> <EOF> [0:52]
      ]]></source>
    </p>

    <p>More examples:</p>

    <table style="table-layout: fixed;">
      <tr>
        <td>
          1) Unclosed paragraph HTML tag. As you see in the tree, content of the paragraph tag is
          not nested to this tag.
          That is because HTML tags are not closed by pair tag &lt;/p&gt;, and Checkstyle requires
          <a href="#Tight-HTML_rules">Tight-HTML</a> code to predictably parse Javadoc comments.
        </td>
        <td>
          2) Here is correct version with open and closed HTML tags.
        </td>
      </tr>

      <tr>
        <td>
          <source><![CDATA[
<p> First
<p> Second
          ]]></source>
        </td>
        <td>
          <source><![CDATA[
<p> First </p>
<p> Second </p>
          ]]></source>
        </td>
      </tr>

      <tr>
        <td>
          <source><![CDATA[
JAVADOC -> JAVADOC [0:0]
|--HTML_ELEMENT -> HTML_ELEMENT [0:0]
|   `--P_TAG_START -> P_TAG_START [0:0]
|       |--START -> < [0:0]
|       |--P_HTML_TAG_NAME -> p [0:1]
|       `--END -> > [0:2]
|--TEXT ->  First [0:3]
|--NEWLINE -> \n [0:9]
|--HTML_ELEMENT -> HTML_ELEMENT [1:0]
|   `--P_TAG_START -> P_TAG_START [1:0]
|       |--START -> < [1:0]
|       |--P_HTML_TAG_NAME -> p [1:1]
|       `--END -> > [1:2]
|--TEXT ->  Second [1:3]
`--EOF -> <EOF> [1:10]
          ]]></source>
        </td>
        <td>
          <source><![CDATA[
JAVADOC -> JAVADOC [0:0]
|--HTML_ELEMENT -> HTML_ELEMENT [0:0]
|   `--PARAGRAPH -> PARAGRAPH [0:0]
|       |--P_TAG_START -> P_TAG_START [0:0]
|       |   |--START -> < [0:0]
|       |   |--P_HTML_TAG_NAME -> p [0:1]
|       |   `--END -> > [0:2]
|       |--TEXT ->  First  [0:3]
|       `--P_TAG_END -> P_TAG_END [0:10]
|           |--START -> < [0:10]
|           |--SLASH -> / [0:11]
|           |--P_HTML_TAG_NAME -> p [0:12]
|           `--END -> > [0:13]
|--NEWLINE -> \n [0:14]
|--HTML_ELEMENT -> HTML_ELEMENT [1:0]
|   `--PARAGRAPH -> PARAGRAPH [1:0]
|       |--P_TAG_START -> P_TAG_START [1:0]
|       |   |--START -> < [1:0]
|       |   |--P_HTML_TAG_NAME -> p [1:1]
|       |   `--END -> > [1:2]
|       |--TEXT ->  Second  [1:3]
|       `--P_TAG_END -> P_TAG_END [1:11]
|           |--START -> < [1:11]
|           |--SLASH -> / [1:12]
|           |--P_HTML_TAG_NAME -> p [1:13]
|           `--END -> > [1:14]
`--EOF -> <EOF> [1:15]
          ]]></source>
        </td>
      </tr>
    </table>

    <p>
        Checks can also be configured to log violation on encountering non-tight HTML tags.
        <tt>violateExecutionOnNonTightHtml</tt> property can be used for this purpose in the checks
        that support it. A custom check needs to extend <tt>AbstractJavadocCheck</tt> for having
        this functionality readily available. Do note that a check which has this property set to
        true will log violation only for the first not-tight HTML tag found. To allow a check to
        skip processing of javadocs with non-tight HTML, method
        <tt>acceptJavadocWithNonTightHtml</tt> in class <tt>AbstractJavadocCheck</tt> can be
        overridden in the check. The following example illustrates how to use this property.
    </p>

    <p>
    Input:
    </p>

    <source><![CDATA[
/**
  * <body>
  * <p> This class is only meant for testing. </p>
  * <p> This p tag is not closed. It is non-tight. Will lead to violations if
  * <tt>violateExecutionOnNonTightHtml</tt> is set to true for the check.
  * <li>tight li tag <p>non-tight p tag, but only the 1st non-tight tag is logged in violation</li>
  * </body>
  */
 public class Test {
     /**
      <p><p>
      paraception. Will result in a violation from the <tt>JavadocParagraph</tt> check due to
      redundant tags.
      </p></p>
      */
     private int field1;

     /**<tr> Zero </p> nesting despite `tr` is closed </tr>*/
     private int field2;

     /**
      * <p> this paragraph is closed and would be nested in javadoc tree </p>
      * <li> this list has an <p> unclosed para, but still the list would get nested </li>
      */
     private int field3;

     /**
      * <li> Complete <p> nesting </p> </li>
      */
     private int field4;
}
    ]]></source>

    <p>
        Output with <tt>violateExecutionOnNonTightHtml</tt> set to false:
    </p>

      <div class="wrapper">
        <table>
          <tr>
            <td>
              <source><![CDATA[
<!DOCTYPE module PUBLIC
          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
          "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
  <module name="TreeWalker">
    <module name="JavadocParagraph">
      <property name="violateExecutionOnNonTightHtml" value="false"/>
    </module>
  </module>
</module>
              ]]></source>
            </td>

            <td>
              <source><![CDATA[
Starting audit...
[ERROR] Test.java:11: Redundant <p> tag. [JavadocParagraph]
Audit done.
Checkstyle ends with 1 errors.
              ]]></source>
            </td>
          </tr>
        </table>
      </div>

    <p>
        Output with <tt>violateExecutionOnNonTightHtml</tt> set to true:
    </p>

      <div class="wrapper">
        <table>
          <tr>
            <td>
              <source><![CDATA[
<!DOCTYPE module PUBLIC
          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
          "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
  <module name="TreeWalker">
    <module name="JavadocParagraph">
      <property name="violateExecutionOnNonTightHtml" value="true"/>
    </module>
  </module>
</module>
              ]]></source>
            </td>

            <td>
              <source><![CDATA[
Starting audit...
[ERROR] Test.java:4: Unclosed HTML tag found: p [JavadocParagraph]
[ERROR] Test.java:11: Redundant <p> tag. [JavadocParagraph]
[ERROR] Test.java:11: Unclosed HTML tag found: p [JavadocParagraph]
[ERROR] Test.java:18: Unclosed HTML tag found: tr [JavadocParagraph]
[ERROR] Test.java:23: Unclosed HTML tag found: p [JavadocParagraph]
Audit done.
Checkstyle ends with 5 errors.
              ]]></source>
            </td>
          </tr>
        </table>
      </div>
    </section>

    <section name="Checkstyle SDK GUI">
      <p>
       Checkstyle GUI allows to showing javadoc tree in java files. To run in use
      </p>
      <div class="wrap-content">
        <source>
          java -cp checkstyle-${projectVersion}-all.jar com.puppycrawl.tools.checkstyle.gui.Main
        </source>
      </div>
      <p>
       and choose "JAVA WITH JAVADOC MODE" in dropdown list in bottom of frame.
      </p>
      <p>
       Now you can see parsed javadoc tree as child of comment block.
      </p>
      <p>
        <span class="wrapper block">
          <img alt="screenshot" src="images/gui_javadoc_screenshot.png"/>
        </span>
      </p>
      <p>
       Notice that only files with ".java" extension can be opened.
      </p>
      <p>
       For detail reference you can see
       <a href="https://checkstyle.org/writingchecks.html#The_Checkstyle_SDK_Gui">
           Checkstyle GUI documentation</a>.
      </p>
    </section>

    <section name="Customize token types in Javadoc Checks">
      <p>
        Java checks controlled by method <a href="writingchecks.html#Understanding_token_sets">
          setTokens(), getDefaultTokens(), getAccessibleTokens(), getRequiredTokens(). </a>
        JavaDoc checks use the same model plus extra 4 methods for Javadoc tokens.
        As Java AST and Javadoc AST are not binded.
        It is highly recommended for Javadoc checks do not use customization of java tokens and
        expect to be executed only on javadoc tokens.
      </p>
      <p>
        There are four methods in AbstractJavadocCheck class to control the processed
        <a href="apidocs/index.html">JavadocTokenTypes</a> -
        one setter
        <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#setJavadocTokens-java.lang.String...-">
        setJavadocTokens()</a>, which is used to define a custom set (which is different
        from the default one) of the processed JavadocTokenTypes via config file and
        three getters, which have to be overridden:
        <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">
        getDefaultJavadocTokens()</a>,
        <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getAcceptableJavadocTokens--">
        getAcceptableJavadocTokens()</a>,
        <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getRequiredJavadocTokens--">
        getRequiredJavadocTokens()</a>.
      </p>

      <ul>

        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#setJavadocTokens-java.lang.String...-">
          setJavadocTokens()</a> - method then define actual set of tokens to run on.
        </li>
        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">
          getDefaultJavadocTokens()</a> - returns a set of JavadocTokenTypes which are processed in
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#visitToken-com.puppycrawl.tools.checkstyle.api.DetailAST-">
          visitToken()</a> method by default.
        </li>

        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getRequiredJavadocTokens--">
          getRequiredJavadocTokens()</a> - returns a set of JavadocTokenTypes which Check must
          be subscribed to for a valid execution. If the user wants to specify a custom set of
          JavadocTokenTypes then this set must contain all the JavadocTokenTypes from
          RequiredJavadocTokens.
        </li>

        <li>
          <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getAcceptableJavadocTokens--">
          getAcceptableJavadocTokens()</a> - returns a set, which contains all the
          JavadocTokenTypes that can be processed by the check. Both DefaultJavadocTokens and
          RequiredJavadocTokens and any custom set of JavadocTokenTypes are subsets of
          AcceptableJavadocTokens.
        </li>

      </ul>
    </section>

    <section name="Integrating new Javadoc Check">
      <p>
      Javadoc Checks as well as regular Checks extend
        <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html">
        AbstractCheck</a> class. So integrating new Javadoc Check is similar to
        <a href="writingchecks.html#Integrate_your_Check">integrating other Checks</a>.
      </p>
    </section>

    <section name="Declare check's external resource locations">
      <p>
      See <a href="writingchecks.html#Declare_check.27s_external_resource_locations">Declare check's
      external resource locations</a>.
      </p>
    </section>

    <section name="Examples of Javadoc Checks">
      <p>
      The best source knowledge about how to write Javadoc Checks
      could be taken from
      <a href="https://github.com/search?q=path%3Asrc%2Fmain%2Fjava+repo%3Acheckstyle%2Fcheckstyle+%22extends+AbstractJavadocCheck%22">
        existing Checks</a>.
      </p>
    </section>

    <section name="Javadoc parser behavior for current HTML version and new HTML version">
      <p>
      This section shows how parser should/will behave during parsing of current HTML version
      and any new HTML version. Current version is HTML4, new version that need to be supported
      is HTML5.
      GeneralToken - mean that after parsing there will be general AstToken - HTML_TAG.
      SpecialToken - mean that after parsing there will be special AstToken - PARAGRAPH, .... .
      </p>
      <p><b>Tags with optional (omittable) end tag:</b></p>
      <div class="wrapper">
        <table style="table-layout: fixed;">
          <tr>
            <th>Input</th>
            <th>Current standard (HTML4)</th>
            <th>Current standard with hasUnclosedTag flag</th>
            <th>After parser update for new standard (HTML5)</th>
            <th>After parser update for new standard with hasUnclosedTag flag</th>
          </tr>
          <tr>
            <td><![CDATA[<p>text</p>]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td>
          </tr>
          <tr>
            <td><![CDATA[<p>text]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td>
          </tr>
          <tr>
            <td>
              <![CDATA[<rb>text</rb>]]>
              <br/><i>New HTML5 tag with optional (omittable) end tag</i>
            </td>
            <td><![CDATA[No errors, Nested tree, GeneralToken]]></td>
            <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td>
          </tr>
          <tr>
            <td>
              <![CDATA[<rb>text]]>
              <br/><i>New HTML5 tag with optional (omittable) end tag</i>
            </td>
            <td><![CDATA[Parse error]]></td>
            <td><![CDATA[Parse error]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td>
            <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td>
          </tr>
          <tr>
            <td>
              <![CDATA[<qwerty>text</qwerty>]]>
              <br/><i>Unknown HTML tag</i>
            </td>
            <td><![CDATA[No errors, Nested tree, GeneralToken]]></td>
            <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td>
            <td><![CDATA[No errors, Nested tree, GeneralToken]]></td>
            <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td>
          </tr>
          <tr>
            <td>
              <![CDATA[<qwerty>text]]>
              <br/><i>Unknown HTML tag</i>
            </td>
            <td><![CDATA[Parse error]]></td>
            <td><![CDATA[Parse error]]></td>
            <td><![CDATA[Parse error]]></td>
            <td><![CDATA[Parse error]]></td>
          </tr>
        </table>
      </div>
      <br/>
      <p><b>Void tags:</b></p>
      <p>
      Note: "Nested"/"Non-Nested" is not applicable for this type of tags - all of them are looks
      like Non-Nested. Flas "hasUnclosedTag" is "false" for all cases.
      </p>
      <div class="wrapper">
        <table style="table-layout: fixed;">
          <tr>
            <th>Input</th>
            <th>Current standard (HTML4)</th>
            <th>After parser update for new standard (HTML5)</th>
          </tr>
          <tr>
            <td><![CDATA[<br/>]]></td>
            <td>No errors, SpecialToken</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td><![CDATA[<br>]]></td>
            <td>No errors, SpecialToken</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td>
              <![CDATA[<embed/>]]>
              <br/><i>New HTML5 tag</i>
            </td>
            <td>No errors, GeneralToken</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td>
              <![CDATA[<embed>]]>
              <br/><i>New HTML5 tag</i>
            </td>
            <td>Parse Error</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td>
              <![CDATA[<basefont/>]]>
              <br/><i>Supported in HTML4. Not supported tag in HTML5</i>
            </td>
            <td>No errors, SpecialToken</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td>
              <![CDATA[<basefont>]]>
              <br/><i>Supported in HTML4. Not supported tag in HTML5</i>
            </td>
            <td>No errors, SpecialToken</td>
            <td>No errors, SpecialToken</td>
          </tr>
          <tr>
            <td>
              <![CDATA[<qwerty/>]]>
              <br/><i>Unknown HTML tag</i>
            </td>
            <td>No errors, GeneralToken</td>
            <td>No errors, GeneralToken</td>
            </tr>
          <tr>
            <td>
              <![CDATA[<qwerty>]]>
              <br/><i>Unknown HTML tag</i>
            </td>
            <td>Parse Error</td>
            <td>Parse Error</td>
          </tr>
        </table>
      </div>
    </section>

  </body>
</document>
