private void generateDecoder(
        final String className,
        final Token msgToken,
        final List<Token> fields,
        final List<Token> groups,
        final List<Token> varData,
        final boolean hasVarData,
        final FieldPrecedenceModel fieldPrecedenceModel)
        throws IOException
    {
        final String implementsString = implementsInterface(MessageDecoderFlyweight.class.getSimpleName());

        try (Writer out = outputManager.createOutput(className))
        {
            out.append(generateMainHeader(ir.applicableNamespace(), DECODER, hasVarData));

            if (shouldGenerateGroupOrderAnnotation)
            {
                generateAnnotations(BASE_INDENT, className, groups, out, JavaUtil::decoderName);
            }

            out.append(generateDeclaration(className, implementsString, msgToken));
            out.append(generateFieldOrderStates(fieldPrecedenceModel));
            out.append(generateDecoderFlyweightCode(fieldPrecedenceModel, className, msgToken));

            final StringBuilder sb = new StringBuilder();
            generateDecoderFields(sb, fieldPrecedenceModel, fields, BASE_INDENT);
            generateDecoderGroups(sb, fieldPrecedenceModel, className, groups, BASE_INDENT, false);
            generateDecoderVarData(sb, fieldPrecedenceModel, varData, BASE_INDENT);

            generateDecoderDisplay(sb, msgToken.name(), fields, groups, varData);
            generateMessageLength(sb, className, true, groups, varData, BASE_INDENT);

            out.append(sb);
            out.append("}\n");
        }
    }
\n");
        sb.append("     * The states in which a encoder/decoder/codec can live.\n");
        sb.append("     *\n");
        sb.append("     * <p>The state machine diagram below, encoded in the dot language, describes\n");
        sb.append("     * the valid state transitions according to the order in which fields may be\n");
        sb.append("     * accessed safely. Tools such as PlantUML and Graphviz can render it.\n");
        sb.append("     *\n");
        sb.append("     * <pre>{@code\n");
        fieldPrecedenceModel.generateGraph(sb, "     *   ");
        sb.append("     * }</pre>\n");
        sb.append("
sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java