Validate the docstring.

    Parameters
    ----------
    doc : Docstring
        A Docstring object with the given function name.

    Returns
    -------
    tuple
        errors : list of tuple
            Errors occurred during validation.
        warnings : list of tuple
            Warnings occurred during validation.
        examples_errs : str
            Examples usage displayed along the error, otherwise empty string.

    Notes
    -----
    The errors codes are defined as:
    - First two characters: Section where the error happens:
       * GL: Global (no section, like section ordering errors)
       * SS: Short summary
       * ES: Extended summary
       * PR: Parameters
       * RT: Returns
       * YD: Yields
       * RS: Raises
       * WN: Warns
       * SA: See Also
       * NT: Notes
       * RF: References
       * EX: Examples
    - Last two characters: Numeric error code inside the section

    For example, EX02 is the second codified error in the Examples section
    (which in this case is assigned to examples that do not pass the tests).

    The error codes, their corresponding error messages, and the details on how
    they are validated, are not documented more than in the source code of this
    function.

def get_validation_data(doc):
    """
    Validate the docstring.

    Parameters
    ----------
    doc : Docstring
        A Docstring object with the given function name.

    Returns
    -------
    tuple
        errors : list of tuple
            Errors occurred during validation.
        warnings : list of tuple
            Warnings occurred during validation.
        examples_errs : str
            Examples usage displayed along the error, otherwise empty string.

    Notes
    -----
    The errors codes are defined as:
    - First two characters: Section where the error happens:
       * GL: Global (no section, like section ordering errors)
       * SS: Short summary
       * ES: Extended summary
       * PR: Parameters
       * RT: Returns
       * YD: Yields
       * RS: Raises
       * WN: Warns
       * SA: See Also
       * NT: Notes
       * RF: References
       * EX: Examples
    - Last two characters: Numeric error code inside the section

    For example, EX02 is the second codified error in the Examples section
    (which in this case is assigned to examples that do not pass the tests).

    The error codes, their corresponding error messages, and the details on how
    they are validated, are not documented more than in the source code of this
    function.
    """

    errs = []
    wrns = []
    if not doc.raw_doc:
        errs.append(error('GL08'))
        return errs, wrns, ''

    if doc.start_blank_lines != 1:
        errs.append(error('GL01'))
    if doc.end_blank_lines != 1:
        errs.append(error('GL02'))
    if doc.double_blank_lines:
        errs.append(error('GL03'))
    mentioned_errs = doc.mentioned_private_classes
    if mentioned_errs:
        errs.append(error('GL04',
                          mentioned_private_classes=', '.join(mentioned_errs)))
    for line in doc.raw_doc.splitlines():
        if re.match("^ *\t", line):
            errs.append(error('GL05', line_with_tabs=line.lstrip()))

    unexpected_sections = [section for section in doc.section_titles
                           if section not in ALLOWED_SECTIONS]
    for section in unexpected_sections:
        errs.append(error('GL06',
                          section=section,
                          allowed_sections=', '.join(ALLOWED_SECTIONS)))

    correct_order = [section for section in ALLOWED_SECTIONS
                     if section in doc.section_titles]
    if correct_order != doc.section_titles:
        errs.append(error('GL07',
                          correct_sections=', '.join(correct_order)))

    if (doc.deprecated_with_directive
            and not doc.extended_summary.startswith('.. deprecated:: ')):
        errs.append(error('GL09'))

    if not doc.summary:
        errs.append(error('SS01'))
    else:
        if not doc.summary[0].isupper():
            errs.append(error('SS02'))
        if doc.summary[-1] != '.':
            errs.append(error('SS03'))
        if doc.summary != doc.summary.lstrip():
            errs.append(error('SS04'))
        elif (doc.is_function_or_method
                and doc.summary.split(' ')[0][-1] == 's'):
            errs.append(error('SS05'))
        if doc.num_summary_lines > 1:
            errs.append(error('SS06'))

    if not doc.extended_summary:
        wrns.append(('ES01', 'No extended summary found'))

    # PR01: Parameters not documented
    # PR02: Unknown parameters
    # PR03: Wrong parameters order
    errs += doc.parameter_mismatches

    for param in doc.doc_parameters:
        if not param.startswith("*"):  # Check can ignore var / kwargs
            if not doc.parameter_type(param):
                if ':' in param:
                    errs.append(error('PR10',
                                      param_name=param.split(':')[0]))
                else:
                    errs.append(error('PR04', param_name=param))
            else:
                if doc.parameter_type(param)[-1] == '.':
                    errs.append(error('PR05', param_name=param))
                common_type_errors = [('integer', 'int'),
                                      ('boolean', 'bool'),
                                      ('string', 'str')]
                for wrong_type, right_type in common_type_errors:
                    if wrong_type in doc.parameter_type(param):
                        errs.append(error('PR06',
                                          param_name=param,
                                          right_type=right_type,
                                          wrong_type=wrong_type))
        if not doc.parameter_desc(param):
            errs.append(error('PR07', param_name=param))
        else:
            if not doc.parameter_desc(param)[0].isupper():
                errs.append(error('PR08', param_name=param))
            if doc.parameter_desc(param)[-1] != '.':
                errs.append(error('PR09', param_name=param))

    if doc.is_function_or_method:
        if not doc.returns:
            if doc.method_returns_something:
                errs.append(error('RT01'))
        else:
            if len(doc.returns) == 1 and doc.returns[0].name:
                errs.append(error('RT02'))
            for name_or_type, type_, desc in doc.returns:
                if not desc:
                    errs.append(error('RT03'))
                else:
                    desc = ' '.join(desc)
                    if not desc[0].isupper():
                        errs.append(error('RT04'))
                    if not desc.endswith('.'):
                        errs.append(error('RT05'))

        if not doc.yields and 'yield' in doc.method_source:
            errs.append(error('YD01'))

    if not doc.see_also:
        wrns.append(error('SA01'))
    else:
        for rel_name, rel_desc in doc.see_also.items():
            if rel_desc:
                if not rel_desc.endswith('.'):
                    errs.append(error('SA02', reference_name=rel_name))
                if not rel_desc[0].isupper():
                    errs.append(error('SA03', reference_name=rel_name))
            else:
                errs.append(error('SA04', reference_name=rel_name))
            if rel_name.startswith('pandas.'):
                errs.append(error('SA05',
                                  reference_name=rel_name,
                                  right_reference=rel_name[len('pandas.'):]))

    examples_errs = ''
    if not doc.examples:
        wrns.append(error('EX01'))
    else:
        examples_errs = doc.examples_errors
        if examples_errs:
            errs.append(error('EX02', doctest_log=examples_errs))
        for err in doc.validate_pep8():
            errs.append(error('EX03',
                              error_code=err.error_code,
                              error_message=err.message,
                              times_happening=' ({} times)'.format(err.count)
                                              if err.count > 1 else ''))
        examples_source_code = ''.join(doc.examples_source_code)
        for wrong_import in ('numpy', 'pandas'):
            if 'import {}'.format(wrong_import) in examples_source_code:
                errs.append(error('EX04', imported_library=wrong_import))
    return errs, wrns, examples_errs