#!/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 = [
    'api/video_codecs/video_decoder.h',
    'common_types.cc',
    'common_types.h',
    'examples/objc',
    'media/base/stream_params.h',
    'media/base/video_common.h',
    'modules/audio_coding',
    'modules/audio_device',
    'modules/audio_processing',
    'modules/desktop_capture',
    'modules/include/module_common_types.h',
    'modules/utility',
    'modules/video_capture',
    'p2p/base/pseudo_tcp.cc',
    'p2p/base/pseudo_tcp.h',
    'PRESUBMIT.py',
    'presubmit_test_mocks.py',
    'presubmit_test.py',
    'rtc_base',
    'sdk/android/src/jni',
    'sdk/objc',
    'system_wrappers',
    'test',
    'tools_webrtc',
    'voice_engine',
]

PYLINT_OLD_STYLE = [
    "PRESUBMIT.py",
    "tools_webrtc/autoroller/roll_deps.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+)"')


def FindSrcDirPath(starting_dir):
    """Returns the abs path to the src/ dir of the project."""
    src_dir = starting_dir
    while os.path.basename(src_dir) != 'src':
        src_dir = os.path.normpath(os.path.join(src_dir, os.pardir))
    return src_dir


@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 ABSL_DEPRECATED 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 = []
    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.append(f.LocalPath())
            else:
                # Normal case: Subdirectories not included.
                if dn == path:
                    files.append(f.LocalPath())

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


def CheckNoIOStreamInHeaders(input_api, output_api, source_file_filter):
    """Checks to make sure no .h files include <iostream>."""
    files = []
    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.append(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',
                files)
        ]
    return []


def CheckNoPragmaOnce(input_api, output_api, source_file_filter):
    """Make sure that banned functions are not used."""
    files = []
    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.append(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', 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 = []
    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.append(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 = []
    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.append(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=violating_gn_files)
        ]
    return []


def CheckAbseilDependencies(input_api, gn_files, output_api):
    """Checks that Abseil dependencies are declared in `absl_deps`."""
    absl_re = re.compile(r'third_party/abseil-cpp', re.MULTILINE | re.DOTALL)
    target_types_to_check = [
        'rtc_library',
        'rtc_source_set',
        'rtc_static_library',
        'webrtc_fuzzer_test',
    ]
    error_msg = ('Abseil dependencies in target "%s" (file: %s) '
                 'should be moved to the "absl_deps" parameter.')
    errors = []

    # pylint: disable=too-many-nested-blocks
    for gn_file in gn_files:
        gn_file_content = input_api.ReadFile(gn_file)
        for target_match in TARGET_RE.finditer(gn_file_content):
            target_type = target_match.group('target_type')
            target_name = target_match.group('target_name')
            target_contents = target_match.group('target_contents')
            if target_type in target_types_to_check:
                for deps_match in DEPS_RE.finditer(target_contents):
                    deps = deps_match.group('deps').splitlines()
                    for dep in deps:
                        if re.search(absl_re, dep):
                            errors.append(
                                output_api.PresubmitError(
                                    error_msg %
                                    (target_name, gn_file.LocalPath())))
                            break  # no need to warn more than once per target
    return errors


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 '
        'rtc::SimpleStringBuilder\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 = []
    for f in input_api.AffectedSourceFiles(file_filter):
        gn_files.append(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(CheckAbseilDependencies(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 RunGnCheck
    errors = RunGnCheck(FindSrcDirPath(input_api.PresubmitLocalPath()))[: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 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__.
    src_path = FindSrcDirPath(input_api.PresubmitLocalPath())
    checkdeps_path = input_api.os_path.join(src_path, '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(),
        Join('rtc_tools', 'py_event_log_analyzer'),
    ] + [
        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 = []
    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.append(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, 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)))

    # 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',
            ]))
    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(
        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(
        CheckObjcApiSymbols(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 = []
    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.append(f)
                break

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


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 = []
    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.append(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:', 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 = []
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        for _, line in f.ChangedContents():
            if pattern.search(line):
                files.append(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:', 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 = []
    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.append(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.', 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,
    }
    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 []
