#!/usr/bin/env vpython3

# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

import json
import os
import re
import sys
from collections import defaultdict
from contextlib import contextmanager

# Runs PRESUBMIT.py in py3 mode by git cl presubmit.
USE_PYTHON3 = True

# Files and directories that are *skipped* by cpplint in the presubmit script.
CPPLINT_EXCEPTIONS = [
    'examples/objc',
    'modules/audio_coding',
    'modules/audio_device',
    'modules/audio_processing',
    'modules/desktop_capture',
    'modules/utility',
    'modules/video_capture',
    'PRESUBMIT.py',
    'presubmit_test_mocks.py',
    'presubmit_test.py',
    'rtc_base',
    'sdk/android/src/jni',
    'sdk/objc',
    'test',
    'tools_webrtc',
]

PYLINT_OLD_STYLE = [
    "PRESUBMIT.py",
    "presubmit_test.py",
    "presubmit_test_mocks.py",
    "tools_webrtc/autoroller/roll_deps.py",
    "tools_webrtc/android/build_aar.py",
    "tools_webrtc/ios/build_ios_libs.py",
    "tools_webrtc/mb/mb.py",
    "tools_webrtc/mb/mb_unittest.py",
]

# These filters will always be removed, even if the caller specifies a filter
# set, as they are problematic or broken in some way.
#
# Justifications for each filter:
# - build/c++11         : Rvalue ref checks are unreliable (false positives),
#                         include file and feature blocklists are
#                         google3-specific.
# - readability/todo    : WebRTC puts bug links, not usernames, in TODOs.
#                         The new TODO style also doesn't match with this check.
# - runtime/references  : Mutable references are not banned by the Google
#                         C++ style guide anymore (starting from May 2020).
# - whitespace/operators: Same as above (doesn't seem sufficient to eliminate
#                         all move-related errors).
DISABLED_LINT_FILTERS = [
    '-build/c++11',
    '-readability/todo',
    '-runtime/references',
    '-whitespace/operators',
]

# List of directories of "supported" native APIs. That means changes to headers
# will be done in a compatible way following this scheme:
# 1. Non-breaking changes are made.
# 2. The old APIs as marked as deprecated (with comments).
# 3. Deprecation is announced to discuss-webrtc@googlegroups.com and
#    webrtc-users@google.com (internal list).
# 4. (later) The deprecated APIs are removed.
NATIVE_API_DIRS = (
    'api',  # All subdirectories of api/ are included as well.
    'media/base',
    'media/engine',
    'modules/audio_device/include',
    'pc',
)

# These directories should not be used but are maintained only to avoid breaking
# some legacy downstream code.
LEGACY_API_DIRS = (
    'common_audio/include',
    'modules/audio_coding/include',
    'modules/audio_processing/include',
    'modules/congestion_controller/include',
    'modules/include',
    'modules/remote_bitrate_estimator/include',
    'modules/rtp_rtcp/include',
    'modules/rtp_rtcp/source',
    'modules/utility/include',
    'modules/video_coding/codecs/h264/include',
    'modules/video_coding/codecs/vp8/include',
    'modules/video_coding/codecs/vp9/include',
    'modules/video_coding/include',
    'rtc_base',
    'system_wrappers/include',
)

# NOTE: The set of directories in API_DIRS should be the same as those
# listed in the table in native-api.md.
API_DIRS = NATIVE_API_DIRS[:] + LEGACY_API_DIRS[:]

# TARGET_RE matches a GN target, and extracts the target name and the contents.
TARGET_RE = re.compile(
    r'(?P<indent>\s*)(?P<target_type>\w+)\("(?P<target_name>\w+)"\) {'
    r'(?P<target_contents>.*?)'
    r'(?P=indent)}', re.MULTILINE | re.DOTALL)

# SOURCES_RE matches a block of sources inside a GN target.
SOURCES_RE = re.compile(r'sources \+?= \[(?P<sources>.*?)\]',
                        re.MULTILINE | re.DOTALL)

# DEPS_RE matches a block of sources inside a GN target.
DEPS_RE = re.compile(r'\bdeps \+?= \[(?P<deps>.*?)\]',
                     re.MULTILINE | re.DOTALL)

# FILE_PATH_RE matches a file path.
FILE_PATH_RE = re.compile(r'"(?P<file_path>(\w|\/)+)(?P<extension>\.\w+)"')


@contextmanager
def _AddToPath(*paths):
    original_sys_path = sys.path
    sys.path.extend(paths)
    try:
        yield
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path


def VerifyNativeApiHeadersListIsValid(input_api, output_api):
    """Ensures the list of native API header directories is up to date."""
    non_existing_paths = []
    native_api_full_paths = [
        input_api.os_path.join(input_api.PresubmitLocalPath(),
                               *path.split('/')) for path in API_DIRS
    ]
    for path in native_api_full_paths:
        if not os.path.isdir(path):
            non_existing_paths.append(path)
    if non_existing_paths:
        return [
            output_api.PresubmitError(
                'Directories to native API headers have changed which has made '
                'the list in PRESUBMIT.py outdated.\nPlease update it to the '
                'current location of our native APIs.', non_existing_paths)
        ]
    return []


API_CHANGE_MSG = """
You seem to be changing native API header files. Please make sure that you:
  1. Make compatible changes that don't break existing clients. Usually
     this is done by keeping the existing method signatures unchanged.
  2. Mark the old stuff as deprecated (use the [[deprecated]] attribute or
     the ABSL_DEPRECATE_AND_INLINE macro).
  3. Create a timeline and plan for when the deprecated stuff will be
     removed. (The amount of time we give users to change their code
     should be informed by how much work it is for them. If they just
     need to replace one name with another or something equally
     simple, 1-2 weeks might be good; if they need to do serious work,
     up to 3 months may be called for.)
  4. Update/inform existing downstream code owners to stop using the
     deprecated stuff. (Send announcements to
     discuss-webrtc@googlegroups.com and webrtc-users@google.com.)
  5. Remove the deprecated stuff, once the agreed-upon amount of time
     has passed.
Related files:
"""


def CheckNativeApiHeaderChanges(input_api, output_api):
    """Checks to remind proper changing of native APIs."""
    files = set()
    source_file_filter = lambda x: input_api.FilterSourceFile(
        x, files_to_check=[r'.+\.(gn|gni|h)$'])
    for f in input_api.AffectedSourceFiles(source_file_filter):
        for path in API_DIRS:
            dn = os.path.dirname(f.LocalPath())
            if path == 'api':
                # Special case: Subdirectories included.
                if dn == 'api' or dn.startswith('api/'):
                    files.add(f.LocalPath())
            else:
                # Normal case: Subdirectories not included.
                if dn == path:
                    files.add(f.LocalPath())

    if files:
        return [output_api.PresubmitNotifyResult(API_CHANGE_MSG, list(files))]
    return []


def CheckNoIOStreamInHeaders(input_api, output_api, source_file_filter):
    """Checks to make sure no .h files include <iostream>."""
    files = set()
    pattern = input_api.re.compile(r'^#include\s*<iostream>',
                                   input_api.re.MULTILINE)
    file_filter = lambda x: (input_api.FilterSourceFile(x) and
                             source_file_filter(x))
    for f in input_api.AffectedSourceFiles(file_filter):
        if not f.LocalPath().endswith('.h'):
            continue
        contents = input_api.ReadFile(f)
        if pattern.search(contents):
            files.add(f)

    if len(files) > 0:
        return [
            output_api.PresubmitError(
                'Do not #include <iostream> in header files, since it inserts '
                'static initialization into every file including the header. '
                'Instead, #include <ostream>. See http://crbug.com/94794',
                list(files))
        ]
    return []


def CheckNoPragmaOnce(input_api, output_api, source_file_filter):
    """Make sure that banned functions are not used."""
    files = set()
    pattern = input_api.re.compile(r'^#pragma\s+once', input_api.re.MULTILINE)
    file_filter = lambda x: (input_api.FilterSourceFile(x) and
                             source_file_filter(x))
    for f in input_api.AffectedSourceFiles(file_filter):
        if not f.LocalPath().endswith('.h'):
            continue
        contents = input_api.ReadFile(f)
        if pattern.search(contents):
            files.add(f)

    if files:
        return [
            output_api.PresubmitError(
                'Do not use #pragma once in header files.\n'
                'See http://www.chromium.org/developers/coding-style'
                '#TOC-File-headers', list(files))
        ]
    return []


def CheckNoFRIEND_TEST(  # pylint: disable=invalid-name
        input_api, output_api, source_file_filter):
    """Make sure that gtest's FRIEND_TEST() macro is not used, the
  FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
  used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
    problems = []

    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h')) and source_file_filter(f))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            if 'FRIEND_TEST(' in line:
                problems.append('    %s:%d' % (f.LocalPath(), line_num))

    if not problems:
        return []
    return [
        output_api.PresubmitPromptWarning(
            'WebRTC\'s code should not use gtest\'s FRIEND_TEST() macro. '
            'Include testsupport/gtest_prod_util.h and use '
            'FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))
    ]


def IsLintDisabled(disabled_paths, file_path):
    """ Checks if a file is disabled for lint check."""
    for path in disabled_paths:
        if file_path == path or os.path.dirname(file_path).startswith(path):
            return True
    return False


def CheckApprovedFilesLintClean(input_api,
                                output_api,
                                source_file_filter=None):
    """Checks that all new or non-exempt .cc and .h files pass cpplint.py.
  This check is based on CheckChangeLintsClean in
  depot_tools/presubmit_canned_checks.py but has less filters and only checks
  added files."""
    result = []

    # Initialize cpplint.
    import cpplint
    # Access to a protected member _XX of a client class
    # pylint: disable=W0212
    cpplint._cpplint_state.ResetErrorCounts()

    lint_filters = cpplint._Filters()
    lint_filters.extend(DISABLED_LINT_FILTERS)
    cpplint._SetFilters(','.join(lint_filters))

    # Create a platform independent exempt list for cpplint.
    disabled_paths = [
        input_api.os_path.join(*path.split('/')) for path in CPPLINT_EXCEPTIONS
    ]

    # Use the strictest verbosity level for cpplint.py (level 1) which is the
    # default when running cpplint.py from command line. To make it possible to
    # work with not-yet-converted code, we're only applying it to new (or
    # moved/renamed) files and files not listed in CPPLINT_EXCEPTIONS.
    verbosity_level = 1
    files = set()
    for f in input_api.AffectedSourceFiles(source_file_filter):
        # Note that moved/renamed files also count as added.
        if f.Action() == 'A' or not IsLintDisabled(disabled_paths,
                                                   f.LocalPath()):
            files.add(f.AbsoluteLocalPath())

    for file_name in files:
        cpplint.ProcessFile(file_name, verbosity_level)

    if cpplint._cpplint_state.error_count > 0:
        if input_api.is_committing:
            res_type = output_api.PresubmitError
        else:
            res_type = output_api.PresubmitPromptWarning
        result = [res_type('Changelist failed cpplint.py check.')]

    return result


def CheckNoSourcesAbove(input_api, gn_files, output_api):
    # Disallow referencing source files with paths above the GN file location.
    source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
                                          re.MULTILINE | re.DOTALL)
    file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"')
    violating_gn_files = set()
    violating_source_entries = set()
    for gn_file in gn_files:
        contents = input_api.ReadFile(gn_file)
        for source_block_match in source_pattern.finditer(contents):
            # Find all source list entries starting with ../ in the source block
            # (exclude overrides entries).
            for file_list_match in file_pattern.finditer(
                    source_block_match.group(1)):
                source_file = file_list_match.group(1)
                if 'overrides/' not in source_file:
                    violating_source_entries.add(source_file)
                    violating_gn_files.add(gn_file)
    if violating_gn_files:
        return [
            output_api.PresubmitError(
                'Referencing source files above the directory of the GN file '
                'is not allowed. Please introduce new GN targets in the proper '
                'location instead.\n'
                'Invalid source entries:\n'
                '%s\n'
                'Violating GN files:' % '\n'.join(violating_source_entries),
                items=list(violating_gn_files))
        ]
    return []


def CheckNoMixingSources(input_api, gn_files, output_api):
    """Disallow mixing C, C++ and Obj-C/Obj-C++ in the same target.

  See bugs.webrtc.org/7743 for more context.
  """

    def _MoreThanOneSourceUsed(*sources_lists):
        sources_used = 0
        for source_list in sources_lists:
            if len(source_list) > 0:
                sources_used += 1
        return sources_used > 1

    errors = defaultdict(lambda: [])
    for gn_file in gn_files:
        gn_file_content = input_api.ReadFile(gn_file)
        for target_match in TARGET_RE.finditer(gn_file_content):
            # list_of_sources is a list of tuples of the form
            # (c_files, cc_files, objc_files) that keeps track of all the
            # sources defined in a target. A GN target can have more that
            # on definition of sources (since it supports if/else statements).
            # E.g.:
            # rtc_static_library("foo") {
            #   if (is_win) {
            #     sources = [ "foo.cc" ]
            #   } else {
            #     sources = [ "foo.mm" ]
            #   }
            # }
            # This is allowed and the presubmit check should support this case.
            list_of_sources = []
            c_files = []
            cc_files = []
            objc_files = []
            target_name = target_match.group('target_name')
            target_contents = target_match.group('target_contents')
            for sources_match in SOURCES_RE.finditer(target_contents):
                if '+=' not in sources_match.group(0):
                    if c_files or cc_files or objc_files:
                        list_of_sources.append((c_files, cc_files, objc_files))
                    c_files = []
                    cc_files = []
                    objc_files = []
                for file_match in FILE_PATH_RE.finditer(
                        sources_match.group(1)):
                    file_path = file_match.group('file_path')
                    extension = file_match.group('extension')
                    if extension == '.c':
                        c_files.append(file_path + extension)
                    if extension == '.cc':
                        cc_files.append(file_path + extension)
                    if extension in ['.m', '.mm']:
                        objc_files.append(file_path + extension)
            list_of_sources.append((c_files, cc_files, objc_files))
            for c_files_list, cc_files_list, objc_files_list in list_of_sources:
                if _MoreThanOneSourceUsed(c_files_list, cc_files_list,
                                          objc_files_list):
                    all_sources = sorted(c_files_list + cc_files_list +
                                         objc_files_list)
                    errors[gn_file.LocalPath()].append(
                        (target_name, all_sources))
    if errors:
        return [
            output_api.PresubmitError(
                'GN targets cannot mix .c, .cc and .m (or .mm) source files.\n'
                'Please create a separate target for each collection of '
                'sources.\n'
                'Mixed sources: \n'
                '%s\n'
                'Violating GN files:\n%s\n' %
                (json.dumps(errors, indent=2), '\n'.join(list(errors.keys()))))
        ]
    return []


def CheckNoPackageBoundaryViolations(input_api, gn_files, output_api):
    cwd = input_api.PresubmitLocalPath()
    with _AddToPath(
            input_api.os_path.join(cwd, 'tools_webrtc',
                                   'presubmit_checks_lib')):
        from check_package_boundaries import CheckPackageBoundaries
    build_files = [
        os.path.join(cwd, gn_file.LocalPath()) for gn_file in gn_files
    ]
    errors = CheckPackageBoundaries(cwd, build_files)[:5]
    if errors:
        return [
            output_api.PresubmitError(
                'There are package boundary violations in the following GN '
                'files:',
                long_text='\n\n'.join(str(err) for err in errors))
        ]
    return []


def _ReportFileAndLine(filename, line_num):
    """Default error formatter for _FindNewViolationsOfRule."""
    return '%s (line %s)' % (filename, line_num)


def CheckNoWarningSuppressionFlagsAreAdded(gn_files,
                                           input_api,
                                           output_api,
                                           error_formatter=_ReportFileAndLine):
    """Ensure warning suppression flags are not added without a reason."""
    msg = ('Usage of //build/config/clang:extra_warnings is discouraged '
           'in WebRTC.\n'
           'If you are not adding this code (e.g. you are just moving '
           'existing code) or you want to add an exception,\n'
           'you can add a comment on the line that causes the problem:\n\n'
           '"-Wno-odr"  # no-presubmit-check TODO(bugs.webrtc.org/BUG_ID)\n'
           '\n'
           'Affected files:\n')
    errors = []  # 2-element tuples with (file, line number)
    clang_warn_re = input_api.re.compile(
        r'//build/config/clang:extra_warnings')
    # pylint: disable-next=fixme
    no_presubmit_re = input_api.re.compile(
        r'# no-presubmit-check TODO\(bugs\.webrtc\.org/\d+\)')
    for f in gn_files:
        for line_num, line in f.ChangedContents():
            if clang_warn_re.search(line) and not no_presubmit_re.search(line):
                errors.append(error_formatter(f.LocalPath(), line_num))
    if errors:
        return [output_api.PresubmitError(msg, errors)]
    return []


def CheckNoTestCaseUsageIsAdded(input_api,
                                output_api,
                                source_file_filter,
                                error_formatter=_ReportFileAndLine):
    error_msg = ('Usage of legacy GoogleTest API detected!\nPlease use the '
                 'new API: https://github.com/google/googletest/blob/master/'
                 'googletest/docs/primer.md#beware-of-the-nomenclature.\n'
                 'Affected files:\n')
    errors = []  # 2-element tuples with (file, line number)
    test_case_re = input_api.re.compile(r'TEST_CASE')
    file_filter = lambda f: (source_file_filter(f) and f.LocalPath().endswith(
        '.cc'))
    for f in input_api.AffectedSourceFiles(file_filter):
        for line_num, line in f.ChangedContents():
            if test_case_re.search(line):
                errors.append(error_formatter(f.LocalPath(), line_num))
    if errors:
        return [output_api.PresubmitError(error_msg, errors)]
    return []


def CheckNoStreamUsageIsAdded(input_api,
                              output_api,
                              source_file_filter,
                              error_formatter=_ReportFileAndLine):
    """Make sure that no more dependencies on stringstream are added."""
    error_msg = (
        'Usage of <sstream>, <istream> and <ostream> in WebRTC is '
        'deprecated.\n'
        'This includes the following types:\n'
        'std::istringstream, std::ostringstream, std::wistringstream, '
        'std::wostringstream,\n'
        'std::wstringstream, std::ostream, std::wostream, std::istream,'
        'std::wistream,\n'
        'std::iostream, std::wiostream.\n'
        'If you are not adding this code (e.g. you are just moving '
        'existing code),\n'
        'you can add a comment on the line that causes the problem:\n\n'
        '#include <sstream>  // no-presubmit-check TODO(webrtc:8982)\n'
        'std::ostream& F() {  // no-presubmit-check TODO(webrtc:8982)\n'
        '\n'
        'If you are adding new code, consider using '
        'webrtc::StringBuilder\n'
        '(in rtc_base/strings/string_builder.h).\n'
        'Affected files:\n')
    errors = []  # 2-element tuples with (file, line number)
    include_re = input_api.re.compile(r'#include <(i|o|s)stream>')
    usage_re = input_api.re.compile(
        r'std::(w|i|o|io|wi|wo|wio)(string)*stream')
    no_presubmit_re = input_api.re.compile(
        r'// no-presubmit-check TODO\(webrtc:8982\)')
    file_filter = lambda x: (input_api.FilterSourceFile(x) and
                             source_file_filter(x))

    def _IsException(file_path):
        is_test = any(
            file_path.endswith(x) for x in
            ['_test.cc', '_tests.cc', '_unittest.cc', '_unittests.cc'])
        return (file_path.startswith('examples')
                or file_path.startswith('test') or is_test)

    for f in input_api.AffectedSourceFiles(file_filter):
        # Usage of stringstream is allowed under examples/ and in tests.
        if f.LocalPath() == 'PRESUBMIT.py' or _IsException(f.LocalPath()):
            continue
        for line_num, line in f.ChangedContents():
            if ((include_re.search(line) or usage_re.search(line))
                    and not no_presubmit_re.search(line)):
                errors.append(error_formatter(f.LocalPath(), line_num))
    if errors:
        return [output_api.PresubmitError(error_msg, errors)]
    return []


def CheckPublicDepsIsNotUsed(gn_files, input_api, output_api):
    """Checks that public_deps is not used without a good reason."""
    result = []
    no_presubmit_check_re = input_api.re.compile(
        r'# no-presubmit-check TODO\(webrtc:\d+\)')
    error_msg = ('public_deps is not recommended in WebRTC BUILD.gn files '
                 'because it doesn\'t map well to downstream build systems.\n'
                 'Used in: %s (line %d).\n'
                 'If you are not adding this code (e.g. you are just moving '
                 'existing code) or you have a good reason, you can add this '
                 'comment (verbatim) on the line that causes the problem:\n\n'
                 'public_deps = [  # no-presubmit-check TODO(webrtc:8603)\n')
    for affected_file in gn_files:
        for (line_number, affected_line) in affected_file.ChangedContents():
            if 'public_deps' in affected_line:
                surpressed = no_presubmit_check_re.search(affected_line)
                if not surpressed:
                    result.append(
                        output_api.PresubmitError(
                            error_msg %
                            (affected_file.LocalPath(), line_number)))
    return result


def CheckCheckIncludesIsNotUsed(gn_files, input_api, output_api):
    result = []
    error_msg = (
        'check_includes overrides are not allowed since it can cause '
        'incorrect dependencies to form. It effectively means that your '
        'module can include any .h file without depending on its '
        'corresponding target. There are some exceptional cases when '
        'this is allowed: if so, get approval from a .gn owner in the '
        'root OWNERS file.\n'
        'Used in: %s (line %d).')
    # pylint: disable-next=fixme
    no_presubmit_re = input_api.re.compile(
        r'# no-presubmit-check TODO\(bugs\.webrtc\.org/\d+\)')
    for affected_file in gn_files:
        for (line_number, affected_line) in affected_file.ChangedContents():
            if ('check_includes' in affected_line
                    and not no_presubmit_re.search(affected_line)):
                result.append(
                    output_api.PresubmitError(
                        error_msg % (affected_file.LocalPath(), line_number)))
    return result


def CheckGnChanges(input_api, output_api):
    file_filter = lambda x: (input_api.FilterSourceFile(
        x,
        files_to_check=(r'.+\.(gn|gni)$', ),
        files_to_skip=(r'.*/presubmit_checks_lib/testdata/.*', )))

    gn_files = set()
    for f in input_api.AffectedSourceFiles(file_filter):
        gn_files.add(f)

    result = []
    if gn_files:
        result.extend(CheckNoSourcesAbove(input_api, gn_files, output_api))
        result.extend(CheckNoMixingSources(input_api, gn_files, output_api))
        result.extend(
            CheckNoPackageBoundaryViolations(input_api, gn_files, output_api))
        result.extend(CheckPublicDepsIsNotUsed(gn_files, input_api,
                                               output_api))
        result.extend(
            CheckCheckIncludesIsNotUsed(gn_files, input_api, output_api))
        result.extend(
            CheckNoWarningSuppressionFlagsAreAdded(gn_files, input_api,
                                                   output_api))
    return result


def CheckGnGen(input_api, output_api):
    """Runs `gn gen --check` with default args to detect mismatches between
  #includes and dependencies in the BUILD.gn files, as well as general build
  errors.
  """
    with _AddToPath(
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'tools_webrtc', 'presubmit_checks_lib')):
        from build_helpers import run_gn_check
    errors = run_gn_check(input_api.change.RepositoryRoot())[:5]
    if errors:
        return [
            output_api.PresubmitPromptWarning(
                'Some #includes do not match the build dependency graph. '
                'Please run:\n'
                '  gn gen --check <out_dir>',
                long_text='\n\n'.join(errors))
        ]
    return []


def CheckDeps(input_api, output_api):
    """Runs checkdeps """
    repo_root = input_api.change.RepositoryRoot()
    checkdeps_path = input_api.os_path.join(repo_root, 'buildtools',
                                            'checkdeps')
    with _AddToPath(checkdeps_path):
        import checkdeps

    deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
    deps_checker.CheckDirectory(input_api.PresubmitLocalPath())
    results = []
    if deps_checker.results_formatter.GetResults():
        results.append(
            output_api.PresubmitError('\n'.join(
                deps_checker.results_formatter.GetResults())))
    return results


def CheckUnwantedDependencies(input_api, output_api, source_file_filter):
    """Runs checkdeps on #include statements added in this
  change. Breaking - rules is an error, breaking ! rules is a
  warning.
  """
    # Copied from Chromium's src/PRESUBMIT.py.

    # We need to wait until we have an input_api object and use this
    # roundabout construct to import checkdeps because this file is
    # eval-ed and thus doesn't have __file__.
    repo_root = input_api.change.RepositoryRoot()
    checkdeps_path = input_api.os_path.join(repo_root, 'buildtools',
                                            'checkdeps')
    if not os.path.exists(checkdeps_path):
        return [
            output_api.PresubmitError(
                'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
                'download all the DEPS entries?' % checkdeps_path)
        ]
    with _AddToPath(checkdeps_path):
        import checkdeps
        from cpp_checker import CppChecker
        from rules import Rule

    added_includes = []
    for f in input_api.AffectedFiles(file_filter=source_file_filter):
        if not CppChecker.IsCppFile(f.LocalPath()):
            continue

        changed_lines = [line for _, line in f.ChangedContents()]
        added_includes.append([f.LocalPath(), changed_lines])

    deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())

    error_descriptions = []
    warning_descriptions = []
    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
            added_includes):
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
        else:
            warning_descriptions.append(description_with_path)

    results = []
    if error_descriptions:
        results.append(
            output_api.PresubmitError(
                'You added one or more #includes that violate checkdeps rules.'
                '\nCheck that the DEPS files in these locations contain valid '
                'rules.\nSee '
                'https://cs.chromium.org/chromium/src/buildtools/checkdeps/ '
                'for more details about checkdeps.', error_descriptions))
    if warning_descriptions:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You added one or more #includes of files that are temporarily'
                '\nallowed but being removed. Can you avoid introducing the\n'
                '#include? See relevant DEPS file(s) for details and contacts.'
                '\nSee '
                'https://cs.chromium.org/chromium/src/buildtools/checkdeps/ '
                'for more details about checkdeps.', warning_descriptions))
    return results


def CheckCommitMessageBugEntry(input_api, output_api):
    """Check that bug entries are well-formed in commit message."""
    bogus_bug_msg = (
        'Bogus Bug entry: %s. Please specify the issue tracker prefix and the '
        'issue number, separated by a colon, e.g. webrtc:123 or chromium:12345.'
    )
    results = []
    for bug in input_api.change.BugsFromDescription():
        bug = bug.strip()
        if bug.lower() == 'none':
            continue
        if 'b/' not in bug and ':' not in bug:
            try:
                if int(bug) > 100000:
                    # Rough indicator for current chromium bugs.
                    prefix_guess = 'chromium'
                else:
                    prefix_guess = 'webrtc'
                results.append(
                    'Bug entry requires issue tracker prefix, e.g. %s:%s' %
                    (prefix_guess, bug))
            except ValueError:
                results.append(bogus_bug_msg % bug)
        elif not (re.match(r'\w+:\d+', bug) or re.match(r'b/\d+', bug)):
            results.append(bogus_bug_msg % bug)
    return [output_api.PresubmitError(r) for r in results]


def CheckChangeHasBugField(input_api, output_api):
    """Requires that the changelist is associated with a bug.

  This check is stricter than the one in depot_tools/presubmit_canned_checks.py
  since it fails the presubmit if the bug field is missing or doesn't contain
  a bug reference.

  This supports both 'BUG=' and 'Bug:' since we are in the process of migrating
  to Gerrit and it encourages the usage of 'Bug:'.
  """
    if input_api.change.BugsFromDescription():
        return []
    return [
        output_api.PresubmitError(
            'The "Bug: [bug number]" footer is mandatory. Please create a '
            'bug and reference it using either of:\n'
            ' * https://bugs.webrtc.org - reference it using Bug: '
            'webrtc:XXXX\n'
            ' * https://crbug.com - reference it using Bug: chromium:XXXXXX')
    ]


def CheckJSONParseErrors(input_api, output_api, source_file_filter):
    """Check that JSON files do not contain syntax errors."""

    def FilterFile(affected_file):
        return (input_api.os_path.splitext(affected_file.LocalPath())[1]
                == '.json' and source_file_filter(affected_file))

    def GetJSONParseError(input_api, filename):
        try:
            contents = input_api.ReadFile(filename)
            input_api.json.loads(contents)
        except ValueError as e:
            return e
        return None

    results = []
    for affected_file in input_api.AffectedFiles(file_filter=FilterFile,
                                                 include_deletes=False):
        parse_error = GetJSONParseError(input_api,
                                        affected_file.AbsoluteLocalPath())
        if parse_error:
            results.append(
                output_api.PresubmitError(
                    '%s could not be parsed: %s' %
                    (affected_file.LocalPath(), parse_error)))
    return results


def RunPythonTests(input_api, output_api):

    def Join(*args):
        return input_api.os_path.join(input_api.PresubmitLocalPath(), *args)

    excluded_files = [
        # These tests should be run manually after webrtc_dashboard_upload
        # target has been built.
        'catapult_uploader_test.py',
        'process_perf_results_test.py',
    ]

    test_directories = [input_api.PresubmitLocalPath()] + [
        root for root, _, files in os.walk(Join('tools_webrtc')) if any(
            f.endswith('_test.py') and f not in excluded_files for f in files)
    ]

    tests = []

    for directory in test_directories:
        tests.extend(
            input_api.canned_checks.GetUnitTestsInDirectory(
                input_api,
                output_api,
                directory,
                files_to_check=[r'.+_test\.py$'],
                run_on_python2=False))
    return input_api.RunTests(tests, parallel=True)


def CheckUsageOfGoogleProtobufNamespace(input_api, output_api,
                                        source_file_filter):
    """Checks that the namespace google::protobuf has not been used."""
    files = set()
    pattern = input_api.re.compile(r'google::protobuf')
    proto_utils_path = os.path.join('rtc_base', 'protobuf_utils.h')
    file_filter = lambda x: (input_api.FilterSourceFile(x) and
                             source_file_filter(x))
    for f in input_api.AffectedSourceFiles(file_filter):
        if f.LocalPath() in [proto_utils_path, 'PRESUBMIT.py']:
            continue
        contents = input_api.ReadFile(f)
        if pattern.search(contents):
            files.add(f)

    if files:
        return [
            output_api.PresubmitError(
                'Please avoid to use namespace `google::protobuf` directly.\n'
                'Add a using directive in `%s` and include that header instead.'
                % proto_utils_path, list(files))
        ]
    return []


def _LicenseHeader(input_api):
    """Returns the license header regexp."""
    # Accept any year number from 2003 to the current year
    current_year = int(input_api.time.strftime('%Y'))
    allowed_years = (str(s) for s in reversed(range(2003, current_year + 1)))
    years_re = '(' + '|'.join(allowed_years) + ')'
    license_header = (
        r'.*? Copyright( \(c\))? %(year)s The WebRTC [Pp]roject [Aa]uthors\. '
        r'All [Rr]ights [Rr]eserved\.\n'
        r'.*?\n'
        r'.*? Use of this source code is governed by a BSD-style license\n'
        r'.*? that can be found in the LICENSE file in the root of the source\n'
        r'.*? tree\. An additional intellectual property rights grant can be '
        r'found\n'
        r'.*? in the file PATENTS\.  All contributing project authors may\n'
        r'.*? be found in the AUTHORS file in the root of the source tree\.\n'
    ) % {
        'year': years_re,
    }
    return license_header


def CommonChecks(input_api, output_api):
    """Checks common to both upload and commit."""
    results = []
    # Filter out files that are in objc or ios dirs from being cpplint-ed since
    # they do not follow C++ lint rules.
    exception_list = input_api.DEFAULT_FILES_TO_SKIP + (
        r".*\bobjc[\\\/].*",
        r".*objc\.[hcm]+$",
    )
    source_file_filter = lambda x: input_api.FilterSourceFile(
        x, None, exception_list)
    results.extend(
        CheckApprovedFilesLintClean(input_api, output_api, source_file_filter))
    results.extend(
        input_api.canned_checks.CheckLicense(input_api, output_api,
                                             _LicenseHeader(input_api)))
    results.extend(
        input_api.canned_checks.CheckSkillFiles(input_api, output_api))

    # TODO(bugs.webrtc.org/12114): Delete this filter and run pylint on
    # all python files. This is a temporary solution.
    python_file_filter = lambda f: (f.LocalPath().endswith('.py') and
                                    source_file_filter(f))
    python_changed_files = [
        f.LocalPath()
        for f in input_api.AffectedFiles(include_deletes=False,
                                         file_filter=python_file_filter)
    ]
    pylint_new_style = [
        f for f in python_changed_files if f not in PYLINT_OLD_STYLE
    ]
    pylint_old_style = [
        f for f in python_changed_files if f in PYLINT_OLD_STYLE
    ]
    if pylint_new_style:
        results.extend(
            input_api.canned_checks.RunPylint(
                input_api,
                output_api,
                files_to_check=pylint_new_style,
                files_to_skip=(
                    r'^base[\\\/].*\.py$',
                    r'^build[\\\/].*\.py$',
                    r'^buildtools[\\\/].*\.py$',
                    r'^infra[\\\/].*\.py$',
                    r'^ios[\\\/].*\.py$',
                    r'^out.*[\\\/].*\.py$',
                    r'^testing[\\\/].*\.py$',
                    r'^third_party[\\\/].*\.py$',
                    r'^tools[\\\/].*\.py$',
                    r'^xcodebuild.*[\\\/].*\.py$',
                ),
                pylintrc='pylintrc',
                version='2.7'))

    if pylint_old_style:
        results.extend(
            input_api.canned_checks.RunPylint(input_api,
                                              output_api,
                                              files_to_check=pylint_old_style,
                                              pylintrc='pylintrc_old_style',
                                              version='2.7'))
    # TODO(bugs.webrtc.org/13606): talk/ is no more, so make below checks
    # simpler. WebRTC can't use the presubmit_canned_checks.PanProjectChecks
    # function since we need to have different license checks in talk/ and
    # webrtc/directories. Instead, hand-picked checks are included below.

    # .m and .mm files are ObjC files. For simplicity we will consider
    # .h files in ObjC subdirectories ObjC headers.
    objc_filter_list = (r'.+\.m$', r'.+\.mm$', r'.+objc\/.+\.h$')
    # Skip long-lines check for DEPS and GN files.
    build_file_filter_list = (r'.+\.gn$', r'.+\.gni$', 'DEPS')
    # Also we will skip most checks for third_party directory.
    third_party_filter_list = (r'(^|.*[\\\/])third_party[\\\/].+', )
    eighty_char_sources = lambda x: input_api.FilterSourceFile(
        x,
        files_to_skip=build_file_filter_list + objc_filter_list +
        third_party_filter_list)
    hundred_char_sources = lambda x: input_api.FilterSourceFile(
        x, files_to_check=objc_filter_list)
    non_third_party_sources = lambda x: input_api.FilterSourceFile(
        x, files_to_skip=third_party_filter_list)

    results.extend(
        input_api.canned_checks.CheckLongLines(
            input_api,
            output_api,
            maxlen=80,
            source_file_filter=eighty_char_sources))
    results.extend(
        input_api.canned_checks.CheckLongLines(
            input_api,
            output_api,
            maxlen=100,
            source_file_filter=hundred_char_sources))
    results.extend(
        input_api.canned_checks.CheckChangeHasNoTabs(
            input_api, output_api, source_file_filter=non_third_party_sources))
    results.extend(
        input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
            input_api, output_api, source_file_filter=non_third_party_sources))
    results.extend(
        input_api.canned_checks.CheckAuthorizedAuthor(
            input_api,
            output_api,
            bot_allowlist=[
                'chromium-webrtc-autoroll@webrtc-ci.iam.gserviceaccount.com',
                'webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com',
                ('swarming-tasks'
                 '@owners-cleanup-prod.google.com.iam.gserviceaccount.com'),
                ('chrome-cherry-picker'
                 '@chops-service-accounts.iam.gserviceaccount.com'),
            ]))
    results.extend(
        input_api.canned_checks.CheckChangeTodoHasOwner(
            input_api, output_api, source_file_filter=non_third_party_sources))
    results.extend(
        input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
    results.extend(CheckNativeApiHeaderChanges(input_api, output_api))
    results.extend(CheckDeps(input_api, output_api))
    results.extend(
        CheckNoIOStreamInHeaders(input_api,
                                 output_api,
                                 source_file_filter=non_third_party_sources))
    results.extend(
        CheckNoPragmaOnce(input_api,
                          output_api,
                          source_file_filter=non_third_party_sources))
    results.extend(
        CheckNoFRIEND_TEST(input_api,
                           output_api,
                           source_file_filter=non_third_party_sources))
    results.extend(CheckGnChanges(input_api, output_api))
    results.extend(
        CheckUnwantedDependencies(input_api,
                                  output_api,
                                  source_file_filter=non_third_party_sources))
    results.extend(
        CheckJSONParseErrors(input_api,
                             output_api,
                             source_file_filter=non_third_party_sources))
    results.extend(RunPythonTests(input_api, output_api))
    results.extend(
        CheckUsageOfGoogleProtobufNamespace(
            input_api, output_api, source_file_filter=non_third_party_sources))
    results.extend(
        CheckOrphanHeaders(input_api,
                           output_api,
                           source_file_filter=non_third_party_sources))
    results.extend(
        CheckNewlineAtTheEndOfProtoFiles(
            input_api, output_api, source_file_filter=non_third_party_sources))
    results.extend(
        CheckLFNewline(input_api, output_api, non_third_party_sources))
    results.extend(
        CheckNoStreamUsageIsAdded(input_api, output_api,
                                  non_third_party_sources))
    results.extend(
        CheckNoTestCaseUsageIsAdded(input_api, output_api,
                                    non_third_party_sources))
    results.extend(CheckAddedDepsHaveTargetApprovals(input_api, output_api))
    results.extend(CheckApiDepsFileIsUpToDate(input_api, output_api))
    results.extend(
        CheckAbslMemoryInclude(input_api, output_api, non_third_party_sources))
    results.extend(
        CheckAssertUsage(input_api, output_api, non_third_party_sources))
    results.extend(
        CheckBannedAbslMakeUnique(input_api, output_api,
                                  non_third_party_sources))
    results.extend(
        CheckBannedAbslOptional(input_api, output_api,
                                non_third_party_sources))
    results.extend(
        CheckObjcApiSymbols(input_api, output_api, non_third_party_sources))
    results.extend(
        CheckConditionalIncludes(input_api, output_api,
                                 non_third_party_sources))
    return results


def CheckApiDepsFileIsUpToDate(input_api, output_api):
    """Check that 'include_rules' in api/DEPS is up to date.

  The file api/DEPS must be kept up to date in order to avoid to avoid to
  include internal header from WebRTC's api/ headers.

  This check is focused on ensuring that 'include_rules' contains a deny
  rule for each root level directory. More focused allow rules can be
  added to 'specific_include_rules'.
  """
    results = []
    api_deps = os.path.join(input_api.PresubmitLocalPath(), 'api', 'DEPS')
    with open(api_deps) as f:
        deps_content = _ParseDeps(f.read())

    include_rules = deps_content.get('include_rules', [])
    dirs_to_skip = set(['api', 'docs'])

    # Only check top level directories affected by the current CL.
    dirs_to_check = set()
    for f in input_api.AffectedFiles():
        path_tokens = [t for t in f.LocalPath().split(os.sep) if t]
        if len(path_tokens) > 1:
            if (path_tokens[0] not in dirs_to_skip and os.path.isdir(
                    os.path.join(input_api.PresubmitLocalPath(),
                                 path_tokens[0]))):
                dirs_to_check.add(path_tokens[0])

    missing_include_rules = set()
    for p in dirs_to_check:
        rule = '-%s' % p
        if rule not in include_rules:
            missing_include_rules.add(rule)

    if missing_include_rules:
        error_msg = [
            'include_rules = [\n',
            '  ...\n',
        ]

        for r in sorted(missing_include_rules):
            error_msg.append('  "%s",\n' % str(r))

        error_msg.append('  ...\n')
        error_msg.append(']\n')

        results.append(
            output_api.PresubmitError(
                'New root level directory detected! WebRTC api/ headers should '
                'not #include headers from \n'
                'the new directory, so please update "include_rules" in file\n'
                '"%s". Example:\n%s\n' % (api_deps, ''.join(error_msg))))

    return results


def CheckBannedAbslMakeUnique(input_api, output_api, source_file_filter):
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h')) and source_file_filter(f))

    files = set()
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        for _, line in f.ChangedContents():
            if 'absl::make_unique' in line:
                files.add(f)
                break

    if files:
        return [
            output_api.PresubmitError(
                'Please use std::make_unique instead of absl::make_unique.\n'
                'Affected files:', list(files))
        ]
    return []


def CheckBannedAbslOptional(input_api, output_api, source_file_filter):
    absl_optional = re.compile(r'absl::(optional|make_optional|nullopt)',
                               re.MULTILINE)
    absl_optional_include = re.compile(r'^#include\s*"absl/types/optional\.h"',
                                       input_api.re.MULTILINE)
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h')) and source_file_filter(f))

    files = set()
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        for _, line in f.ChangedContents():
            if absl_optional.search(line) or absl_optional_include.search(
                    line):
                files.add(f.LocalPath())
                break

    if files:
        return [
            output_api.PresubmitError(
                'Please use std::optional instead of absl::optional.\n'
                'Affected files:', list(files))
        ]
    return []


def CheckConditionalIncludes(input_api, output_api, source_file_filter):
    conditional_includes = {
        '<netinet/in.h>': '"rtc_base/ip_address.h"',
        '<sys/socket.h>': '"rtc_base/net_helpers.h"',
    }
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h')) and source_file_filter(f))
    results = []
    for key, value in conditional_includes.items():
        include_regex = re.compile('^#include ' + key +
                                   '((?!IWYU pragma|no-presubmit-check).)*$')
        files = set()
        for f in input_api.AffectedFiles(include_deletes=False,
                                         file_filter=file_filter):
            for _, line in f.ChangedContents():
                if include_regex.search(line):
                    files.add(f.LocalPath())
                    break

        if files:
            results.append(
                output_api.PresubmitError(
                    'Please include ' + value + ' instead of ' + key +
                    '.\nAffected files:', list(files)))
    return results


def CheckObjcApiSymbols(input_api, output_api, source_file_filter):
    rtc_objc_export = re.compile(r'RTC_OBJC_EXPORT(.|\n){26}',
                                 re.MULTILINE | re.DOTALL)
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.h')) and source_file_filter(f))

    files = set()
    file_filter = lambda x: (input_api.FilterSourceFile(x) and
                             source_file_filter(x))
    for f in input_api.AffectedSourceFiles(file_filter):
        if not f.LocalPath().endswith('.h') or not 'sdk/objc' in f.LocalPath():
            continue
        if f.LocalPath().endswith('sdk/objc/base/RTCMacros.h'):
            continue
        contents = input_api.ReadFile(f)
        for match in rtc_objc_export.finditer(contents):
            export_block = match.group(0)
            if 'RTC_OBJC_TYPE' not in export_block:
                files.add(f.LocalPath())

    if len(files) > 0:
        return [
            output_api.PresubmitError(
                'RTC_OBJC_EXPORT types must be wrapped into an RTC_OBJC_TYPE() '
                + 'macro.\n\n' + 'For example:\n' +
                'RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE(RtcFoo)\n\n' +
                'RTC_OBJC_EXPORT @interface RTC_OBJC_TYPE(RtcFoo)\n\n' +
                'Please fix the following files:', list(files))
        ]
    return []


def CheckAssertUsage(input_api, output_api, source_file_filter):
    pattern = input_api.re.compile(r'\bassert\(')
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h', '.m', '.mm')) and source_file_filter(f))

    files = set()
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        for _, line in f.ChangedContents():
            if pattern.search(line):
                files.add(f.LocalPath())
                break

    if len(files) > 0:
        return [
            output_api.PresubmitError(
                'Usage of assert() has been detected in the following files, '
                'please use RTC_DCHECK() instead.\n Files:', list(files))
        ]
    return []


def CheckAbslMemoryInclude(input_api, output_api, source_file_filter):
    pattern = input_api.re.compile(r'^#include\s*"absl/memory/memory.h"',
                                   input_api.re.MULTILINE)
    file_filter = lambda f: (f.LocalPath().endswith(
        ('.cc', '.h')) and source_file_filter(f))

    files = set()
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        contents = input_api.ReadFile(f)
        if pattern.search(contents):
            continue
        for _, line in f.ChangedContents():
            if 'absl::WrapUnique' in line:
                files.add(f)
                break

    if len(files) > 0:
        return [
            output_api.PresubmitError(
                'Please include "absl/memory/memory.h" header for '
                'absl::WrapUnique.\nThis header may or may not be included '
                'transitively depending on the C++ standard version.',
                list(files))
        ]
    return []


def CheckChangeOnUpload(input_api, output_api):
    results = []
    results.extend(CommonChecks(input_api, output_api))
    results.extend(CheckGnGen(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckGNFormatted(input_api, output_api))
    return results


def CheckChangeOnCommit(input_api, output_api):
    results = []
    results.extend(CommonChecks(input_api, output_api))
    results.extend(VerifyNativeApiHeadersListIsValid(input_api, output_api))
    results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckChangeWasUploaded(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckChangeHasDescription(
            input_api, output_api))
    results.extend(CheckChangeHasBugField(input_api, output_api))
    results.extend(CheckCommitMessageBugEntry(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckTreeIsOpen(
            input_api,
            output_api,
            json_url='http://webrtc-status.appspot.com/current?format=json'))
    return results


def CheckOrphanHeaders(input_api, output_api, source_file_filter):
    # We need to wait until we have an input_api object and use this
    # roundabout construct to import prebubmit_checks_lib because this file is
    # eval-ed and thus doesn't have __file__.
    error_msg = """{} should be listed in {}."""
    results = []
    exempt_paths = [re.escape(os.path.join('tools_webrtc', 'ios', 'SDK'))]

    with _AddToPath(
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'tools_webrtc', 'presubmit_checks_lib')):
        from check_orphan_headers import GetBuildGnPathFromFilePath
        from check_orphan_headers import IsHeaderInBuildGn

    file_filter = lambda x: input_api.FilterSourceFile(
        x, files_to_skip=exempt_paths) and source_file_filter(x)
    for f in input_api.AffectedSourceFiles(file_filter):
        if f.LocalPath().endswith('.h'):
            file_path = os.path.abspath(f.LocalPath())
            root_dir = os.getcwd()
            gn_file_path = GetBuildGnPathFromFilePath(file_path,
                                                      os.path.exists, root_dir)
            in_build_gn = IsHeaderInBuildGn(file_path, gn_file_path)
            if not in_build_gn:
                results.append(
                    output_api.PresubmitError(
                        error_msg.format(f.LocalPath(),
                                         os.path.relpath(gn_file_path))))
    return results


def CheckNewlineAtTheEndOfProtoFiles(input_api, output_api,
                                     source_file_filter):
    """Checks that all .proto files are terminated with a newline."""
    error_msg = 'File {} must end with exactly one newline.'
    results = []
    file_filter = lambda x: input_api.FilterSourceFile(
        x, files_to_check=(r'.+\.proto$', )) and source_file_filter(x)
    for f in input_api.AffectedSourceFiles(file_filter):
        file_path = f.LocalPath()
        with open(file_path) as f:
            lines = f.readlines()
            if len(lines) > 0 and not lines[-1].endswith('\n'):
                results.append(
                    output_api.PresubmitError(error_msg.format(file_path)))
    return results


def CheckLFNewline(input_api, output_api, source_file_filter):
    """Checks that all files have LF newlines."""
    error_msg = 'File {} must use LF newlines.'
    results = []
    file_filter = lambda x: input_api.FilterSourceFile(
        x, files_to_check=(r'.+', )) and source_file_filter(x)
    for f in input_api.AffectedSourceFiles(file_filter):
        file_path = f.LocalPath()
        with open(file_path, 'rb') as f:
            if b'\r\n' in f.read():
                results.append(
                    output_api.PresubmitError(error_msg.format(file_path)))
    return results


def _ExtractAddRulesFromParsedDeps(parsed_deps):
    """Extract the rules that add dependencies from a parsed DEPS file.

  Args:
    parsed_deps: the locals dictionary from evaluating the DEPS file."""
    add_rules = set()
    add_rules.update([
        rule[1:] for rule in parsed_deps.get('include_rules', [])
        if rule.startswith('+') or rule.startswith('!')
    ])
    for _, rules in parsed_deps.get('specific_include_rules', {}).items():
        add_rules.update([
            rule[1:] for rule in rules
            if rule.startswith('+') or rule.startswith('!')
        ])
    return add_rules


def _ParseDeps(contents):
    """Simple helper for parsing DEPS files."""

    # Stubs for handling special syntax in the root DEPS file.
    class VarImpl:

        def __init__(self, local_scope):
            self._local_scope = local_scope

        def Lookup(self, var_name):
            """Implements the Var syntax."""
            try:
                return self._local_scope['vars'][var_name]
            except KeyError as var_not_defined:
                raise Exception('Var is not defined: %s' %
                                var_name) from var_not_defined

    local_scope = {}
    global_scope = {
        'Var': VarImpl(local_scope).Lookup,
        'Str': str,
    }
    exec(contents, global_scope, local_scope)
    return local_scope


def _CalculateAddedDeps(os_path, old_contents, new_contents):
    """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
  a set of DEPS entries that we should look up.

  For a directory (rather than a specific filename) we fake a path to
  a specific filename by adding /DEPS. This is chosen as a file that
  will seldom or never be subject to per-file include_rules.
  """
    # We ignore deps entries on auto-generated directories.
    auto_generated_dirs = ['grit', 'jni']

    old_deps = _ExtractAddRulesFromParsedDeps(_ParseDeps(old_contents))
    new_deps = _ExtractAddRulesFromParsedDeps(_ParseDeps(new_contents))

    added_deps = new_deps.difference(old_deps)

    results = set()
    for added_dep in added_deps:
        if added_dep.split('/')[0] in auto_generated_dirs:
            continue
        # Assume that a rule that ends in .h is a rule for a specific file.
        if added_dep.endswith('.h'):
            results.add(added_dep)
        else:
            results.add(os_path.join(added_dep, 'DEPS'))
    return results


def CheckAddedDepsHaveTargetApprovals(input_api, output_api):
    """When a dependency prefixed with + is added to a DEPS file, we
    want to make sure that the change is reviewed by an OWNER of the
    target file or directory, to avoid layering violations from being
    introduced. This check verifies that this happens.
    """
    virtual_depended_on_files = set()

    file_filter = lambda f: not input_api.re.match(
        r"^third_party[\\\/](WebKit|blink)[\\\/].*", f.LocalPath())
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        filename = input_api.os_path.basename(f.LocalPath())
        if filename == 'DEPS':
            virtual_depended_on_files.update(
                _CalculateAddedDeps(input_api.os_path,
                                    '\n'.join(f.OldContents()),
                                    '\n'.join(f.NewContents())))

    if not virtual_depended_on_files:
        return []

    if input_api.is_committing:
        if input_api.tbr:
            return [
                output_api.PresubmitNotifyResult(
                    '--tbr was specified, skipping OWNERS check for DEPS '
                    'additions')
            ]
        if input_api.dry_run:
            return [
                output_api.PresubmitNotifyResult(
                    'This is a dry run, skipping OWNERS check for DEPS '
                    'additions')
            ]
        if not input_api.change.issue:
            return [
                output_api.PresubmitError(
                    "DEPS approval by OWNERS check failed: this change has "
                    "no change number, so we can't check it for approvals.")
            ]
        output = output_api.PresubmitError
    else:
        output = output_api.PresubmitNotifyResult

    owner_email, reviewers = (
        input_api.canned_checks.GetCodereviewOwnerAndReviewers(
            input_api, None, approval_needed=input_api.is_committing))

    owner_email = owner_email or input_api.change.author_email

    approval_status = input_api.owners_client.GetFilesApprovalStatus(
        virtual_depended_on_files, reviewers.union([owner_email]), [])
    missing_files = [
        f for f in virtual_depended_on_files
        if approval_status[f] != input_api.owners_client.APPROVED
    ]

    # We strip the /DEPS part that was added by
    # _FilesToCheckForIncomingDeps to fake a path to a file in a
    # directory.
    def StripDeps(path):
        start_deps = path.rfind('/DEPS')
        if start_deps != -1:
            return path[:start_deps]
        return path

    unapproved_dependencies = [
        "'+%s'," % StripDeps(path) for path in missing_files
    ]

    if unapproved_dependencies:
        output_list = [
            output(
                'You need LGTM from owners of depends-on paths in DEPS that '
                ' were modified in this CL:\n    %s' %
                '\n    '.join(sorted(unapproved_dependencies)))
        ]
        suggested_owners = input_api.owners_client.SuggestOwners(
            missing_files, exclude=[owner_email])
        output_list.append(
            output('Suggested missing target path OWNERS:\n    %s' %
                   '\n    '.join(suggested_owners or [])))
        return output_list

    return []
