# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Top-level presubmit script for Chromium.

See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts/
for more details about the presubmit API built into depot_tools.
"""

# Pylint directives to disable warnings in cider.
# pylint: disable=bad-indentation
# pylint: disable=g-import-not-at-top

import dataclasses
from typing import Callable
from typing import Optional
from typing import Sequence
from typing import Tuple

PRESUBMIT_VERSION = '2.0.0'

_EXCLUDED_PATHS = (
    # Generated file
    (r'chrome/android/webapk/shell_apk/src/org/chromium'
     r'/webapk/lib/runtime_library/IWebApkApi.java'),
    # File needs to write to stdout to emulate a tool it's replacing.
    r'chrome/updater/mac/keystone/ksadmin.mm',
    # Generated file.
    (r'^components/variations/proto/devtools/'
     r'client_variations.js'),
    # These are video files, not typescript.
    r'^media/test/data/.*.ts',
    r'^net/tools/spdyshark/.*',
    r'^skia/.*',
    r'^third_party/blink/.*',
    r'^third_party/breakpad/.*',
    # sqlite is an imported third party dependency.
    r'^third_party/sqlite/.*',
    r'^v8/.*',
    r'.*MakeFile$',
    r'.+_autogen\.h$',
    r'.+_pb2(_grpc)?\.py$',
    r'^gpu/config/.*_list_json\.cc$',
    r'tools/md_browser/.*\.css$',
    # Test pages for Maps telemetry tests.
    r'tools/perf/page_sets/maps_perf_test.*',
    # Test pages for WebRTC telemetry tests.
    r'tools/perf/page_sets/webrtc_cases.*',
    # Test file compared with generated output.
    r'tools/polymer/tests/html_to_wrapper/.*.html.ts$',
    # Third-party dependency frozen at a fixed version.
    r'chrome/test/data/webui/chromeos/chai_v4.js$',
)

_EXCLUDED_SET_NO_PARENT_PATHS = (
    # It's for historical reasons that blink isn't a top level directory, where
    # it would be allowed to have 'set noparent' to avoid top level owners
    # accidentally +1ing changes.
    'third_party/blink/OWNERS', )

# Fragment of a regular expression that matches C++ and Objective-C++
# implementation files.
_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'

# Fragment of a regular expression that matches C++ and Objective-C++
# header files.
_HEADER_EXTENSIONS = r'\.(h|hpp|hxx)$'

# Paths with sources that don't use //base.
_NON_BASE_DEPENDENT_PATHS = (
    r'^chrome/browser/browser_switcher/bho/',
    r'^tools/win/',
)

# Regular expression that matches code only used for test binaries
# (best effort).
_TEST_CODE_EXCLUDED_PATHS = (
    r'.*/(fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
    # Test support files, like:
    # foo_test_support.cc
    # bar_test_util_linux.cc (suffix)
    # baz_test_base.cc
    r'.+_test_(base|support|util)(_[a-z]+)?%s' % _IMPLEMENTATION_EXTENSIONS,
    # Test suite files, like:
    # foo_browsertest.cc
    # bar_unittest_mac.cc (suffix)
    # baz_unittests.cc (plural)
    r'.+_(api|browser|eg|int|perf|pixel|unit|ui)?test(s)?(_[a-z]+)?%s' %
    _IMPLEMENTATION_EXTENSIONS,
    r'.+_(fuzz|fuzzer)(_[a-z]+)?%s' % _IMPLEMENTATION_EXTENSIONS,
    r'.+sync_service_impl_harness%s' % _IMPLEMENTATION_EXTENSIONS,
    r'.*/(test|tool(s)?)/.*',
    # content_shell is used for running content_browsertests.
    r'content/shell/.*',
    # Web test harness.
    r'content/web_test/.*',
    # Non-production example code.
    r'mojo/examples/.*',
    # Launcher for running iOS tests on the simulator.
    r'testing/iossim/iossim\.mm$',
    # EarlGrey app side code for tests.
    r'ios/.*_app_interface\.mm$',
    # Views Examples code
    r'ui/views/examples/.*',
    # Chromium Codelab
    r'codelabs/*')

_THIRD_PARTY_EXCEPT_BLINK = 'third_party/(?!blink/)'

_TEST_ONLY_WARNING = (
    'You might be calling functions intended only for testing from\n'
    'production code.  If you are doing this from inside another method\n'
    'named as *ForTesting(), then consider exposing things to have tests\n'
    'make that same call directly.\n'
    'If that is not possible, you may put a comment on the same line with\n'
    '  // IN-TEST \n'
    'to tell the PRESUBMIT script that the code is inside a *ForTesting()\n'
    'method and can be ignored. Do not do this inside production code.\n'
    'The android-binary-size trybot will block if the method exists in the\n'
    'release apk.\n'
    'Note: this warning might be a false positive (crbug.com/1196548).')


@dataclasses.dataclass
class BanRule:
    # String pattern. If the pattern begins with a slash, the pattern will be
    # treated as a regular expression instead.
    pattern: str
    # Explanation as a sequence of strings. Each string in the sequence will be
    # printed on its own line.
    explanation: Tuple[str, ...]
    # Whether or not to treat this ban as a fatal error.
    treat_as_error: bool = False
    # Paths that should be excluded from the ban check. Each string is a regular
    # expression that will be matched against the path of the file being checked
    # relative to the root of the source tree.
    excluded_paths: Optional[Sequence[str]] = None
    # If True, surfaces any violation as a Gerrit comment on the CL after
    # running the CQ.
    surface_as_gerrit_lint: Optional[bool] = None


_BANNED_JAVA_IMPORTS: Sequence[BanRule] = (
    BanRule(
        'import java.net.URI;',
        ('Use org.chromium.url.GURL instead of java.net.URI, where possible.',
         ),
        True,
        excluded_paths=(
            (r'net/android/javatests/src/org/chromium/net/'
             r'AndroidProxySelectorTest\.java'),
            r'components/cronet/',
            r'third_party/robolectric/local/',
        ),
    ),
    BanRule(
        'import android.annotation.TargetApi;',
        ('Do not use TargetApi, use @androidx.annotation.RequiresApi instead. '
         'RequiresApi ensures that any calls are guarded by the appropriate '
         'SDK_INT check. See https://crbug.com/1116486.', ), True),
    BanRule(
        'import androidx.test.rule.ActivityTestRule;',
        ('Do not use ActivityTestRule, use '
         'org.chromium.base.test.BaseActivityTestRule instead.', ),
        True,
        excluded_paths=('components/cronet/', ),
    ),
    BanRule(
        'import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;',
        ('Do not use VectorDrawableCompat, use getResources().getDrawable() '
         'to avoid extra indirections. Please also add trace event as the call '
         'might take more than 20 ms to complete.', ),
        True,
    ),
    BanRule(
        'import java.util.Optional',
        ('Prefer @Nullable over Optional/OptionalInt/OptionalDouble/etc. See '
         '//styleguide/java/java.md', ),
        False,
    ),
    BanRule(
        'import static org.junit.Assert.assertThat',
        ('Use com.google.common.truth.Truth.assertThat() instead of '
         'org.junit.Assert.assertThat().', ),
        True,
        excluded_paths=(r'third_party/', ),
    ),
)

_BANNED_JAVA_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        'StrictMode.allowThreadDiskReads()',
        ('Prefer using StrictModeContext.allowDiskReads() to using StrictMode '
         'directly.', ),
        False,
    ),
    BanRule(
        'StrictMode.allowThreadDiskWrites()',
        ('Prefer using StrictModeContext.allowDiskWrites() to using StrictMode '
         'directly.', ),
        False,
    ),
    BanRule(
        '.waitForIdleSync()',
        ('Do not use waitForIdleSync as it masks underlying issues. There is '
         'almost always something else you should wait on instead.', ),
        False,
    ),
    BanRule(
        r'/(?<!\bsuper\.)(?<!\bIntent )\bregisterReceiver\(',
        ('Do not call android.content.Context.registerReceiver (or an '
         'override) directly. Use one of the wrapper methods defined in '
         'org.chromium.base.ContextUtils, such as '
         'registerProtectedBroadcastReceiver, '
         'registerExportedBroadcastReceiver, or '
         'registerNonExportedBroadcastReceiver. See their documentation for '
         'which one to use.', ),
        True,
        excluded_paths=(
            r'.*Test[^a-z]',
            r'third_party/',
            'base/android/java/src/org/chromium/base/ContextUtils.java',
            'chromecast/browser/android/apk/src/org/chromium/chromecast/shell/BroadcastReceiverScope.java',
        ),
    ),
    BanRule(
        r'/(?:extends|new)\s*(?:android.util.)?Property<[A-Za-z.]+,\s*(?:Integer|Float)>',
        ('Do not use Property<..., Integer|Float>, but use FloatProperty or '
         'IntProperty because it will avoid unnecessary autoboxing of '
         'primitives.', ),
    ),
    BanRule(
        'requestLayout()',
        ('Layouts can be expensive. Prefer using ViewUtils.requestLayout(), '
         'which emits a trace event with additional information to help with '
         'scroll jank investigations. See http://crbug.com/1354176.', ),
        False,
        excluded_paths=(
            'ui/android/java/src/org/chromium/ui/base/ViewUtils.java', ),
    ),
    BanRule(
        'ProfileManager.getLastUsedRegularProfile()',
        ('Prefer passing in the Profile reference instead of relying on the '
         'static getLastUsedRegularProfile() call. Only top level entry points '
         '(e.g. Activities) should call this method. Otherwise, the Profile '
         'should either be passed in explicitly or retrieved from an existing '
         'entity with a reference to the Profile (e.g. WebContents).', ),
        False,
        excluded_paths=(r'.*Test[A-Z]?.*\.java', ),
    ),
    BanRule(
        r'/(ResourcesCompat|getResources\(\))\.getDrawable\(\)',
        ('getDrawable() can be expensive. If you have a lot of calls to '
         'GetDrawable() or your code may introduce janks, please put your '
         'calls inside a trace().', ),
        False,
        excluded_paths=(r'.*Test[A-Z]?.*\.java', ),
    ),
    BanRule(
        r'/RecordHistogram\.getHistogram(ValueCount|TotalCount|Samples)ForTesting\(',
        ('Raw histogram counts are easy to misuse; for example they don\'t '
         'reset between batched tests. Use HistogramWatcher to check histogram '
         'records instead.', ),
        False,
        excluded_paths=(
            'base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java',
            'base/test/android/javatests/src/org/chromium/base/test/util/HistogramWatcher.java',
        ),
    ),
    BanRule(
        r'/((announceForAccessibility\()|TYPE_ANNOUNCEMENT)',
        ('Android 16 deprecates accessibility announcements, characterized by '
         'the use of announceForAccessibility or the dispatch of '
         'TYPE_ANNOUNCEMENT accessibility events. See '
         'https://developer.android.com/about/versions/16/behavior-changes-all#disruptive-a11y'
         ' for more details and suggested replacements.', ),
        False,
    ),
    BanRule(
        pattern=
        (r'/((DeviceInfo\.isDesktop\()|IS_DESKTOP_ANDROID|PackageManager\.FEATURE_PC)'
         ),
        explanation=
        ('Usage of IS_DESKTOP_ANDROID build flag or DeviceInfo.isDesktop() '
         'is discouraged. Use system affordances to determine feature '
         'availablility. Refer to https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ui/android/device_form_factor.md for guidelines. '
         'To request an exception, file a bug at '
         'https://b.corp.google.com/issues/new?component=1753515&template=2172655'
         'Once approved, use centralized util DeviceInfo.isDesktop() '
         'instead of direct build flag or PackageManager.FEATURE_PC checks. '
         'Allowances may be granted to only the directories below: '
         '[build/, chrome/, components/, extensions/, infra/, tools/] '
         'Note: in particular we need to avoid components shared with '
         'WebView.', ),
        treat_as_error=False,
        surface_as_gerrit_lint=True,
    ),
    BanRule(
        r'/(?:org\.junit\.)?(?<!\w)Assert\.assertThat\(',
        ('Use com.google.common.truth.Truth.assertThat() instead of '
         'org.junit.Assert.assertThat().', ),
        True,
        excluded_paths=(r'third_party/', ),
    ),
)

_BANNED_JAVASCRIPT_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        r'/\bchrome\.send\b',
        (
            'The use of chrome.send is disallowed in Chrome (context: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/security/handling-messages-from-web-content.md).',
            'Please use mojo instead for new webuis. https://docs.google.com/document/d/1RF-GSUoveYa37eoyZ9EhwMtaIwoW7Z88pIgNZ9YzQi4/edit#heading=h.gkk22wgk6wff',
        ),
        True,
        (
            r'^(?!ash\/webui).+',
            # TODO(crbug.com/1385601): pre-existing violations still need to be
            # cleaned up.
            'ash/webui/common/resources/cr.m.js',
            'ash/webui/common/resources/multidevice_setup/multidevice_setup_browser_proxy.js',
            'ash/webui/common/resources/quick_unlock/lock_screen_constants.ts',
            'ash/webui/common/resources/smb_shares/smb_browser_proxy.js',
            'ash/webui/connectivity_diagnostics/resources/connectivity_diagnostics.ts',
            'ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts',
            'ash/webui/multidevice_debug/resources/logs.js',
            'ash/webui/multidevice_debug/resources/webui.js',
            'ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js',
            'ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js',
            # TODO(b/301634378): Remove violation exception once Scanning App
            # migrated off usage of `chrome.send`.
            'ash/webui/scanning/resources/scanning_browser_proxy.ts',
        ),
    ), )

_BANNED_OBJC_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        'addTrackingRect:',
        (
            'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
            'prohibited. Please use CrTrackingArea instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        False,
    ),
    BanRule(
        r'/NSTrackingArea\W',
        (
            'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
            'instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        False,
    ),
    BanRule(
        'convertPointFromBase:',
        (
            'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
            'Please use |convertPoint:(point) fromView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        'convertPointToBase:',
        (
            'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
            'Please use |convertPoint:(point) toView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        'convertRectFromBase:',
        (
            'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
            'Please use |convertRect:(point) fromView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        'convertRectToBase:',
        (
            'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
            'Please use |convertRect:(point) toView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        'convertSizeFromBase:',
        (
            'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
            'Please use |convertSize:(point) fromView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        'convertSizeToBase:',
        (
            'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
            'Please use |convertSize:(point) toView:nil| instead.',
            'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
        ),
        True,
    ),
    BanRule(
        r'/\s+UTF8String\s*]',
        (
            'The use of -[NSString UTF8String] is dangerous as it can return null',
            'even if |canBeConvertedToEncoding:NSUTF8StringEncoding| returns YES.',
            'Please use |SysNSStringToUTF8| instead.',
        ),
        True,
        excluded_paths=('^third_party/ocmock/OCMock/', ),
    ),
    BanRule(
        r'__unsafe_unretained',
        (
            'The use of __unsafe_unretained is almost certainly wrong, unless',
            'when interacting with NSFastEnumeration or NSInvocation.',
            'Please use __weak in files build with ARC, nothing otherwise.',
        ),
        False,
    ),
    BanRule(
        'freeWhenDone:NO',
        (
            'The use of "freeWhenDone:NO" with the NoCopy creation of ',
            'Foundation types is prohibited.',
        ),
        True,
    ),
    BanRule(
        'This file requires ARC support.',
        (
            'ARC compilation is default in Chromium; do not add boilerplate to ',
            'files that require ARC.',
        ),
        True,
    ),
)

_BANNED_IOS_OBJC_FUNCTIONS = (
    BanRule(
        r'/\bTEST[(]',
        ('TEST() macro should not be used in Objective-C++ code as it does not ',
         'drain the autorelease pool at the end of the test. Use TEST_F() ',
         'macro instead with a fixture inheriting from PlatformTest (or a ',
         'typedef).'),
        True,
    ),
    BanRule(
        r'/\btesting::Test\b',
        ('testing::Test should not be used in Objective-C++ code as it does ',
         'not drain the autorelease pool at the end of the test. Use ',
         'PlatformTest instead.'),
        True,
    ),
    BanRule(
        ' systemImageNamed:',
        ('+[UIImage systemImageNamed:] should not be used to create symbols.',
         'Instead use a wrapper defined in:',
         'ios/chrome/browser/shared/ui/symbols/symbol_helpers.h'),
        True,
        excluded_paths=(
            'ios/chrome/browser/shared/ui/symbols/symbol_helpers.mm',
            'ios/chrome/common',
            # App extensions have restricted dependencies and thus can't use the
            # wrappers.
            r'^ios/chrome/\w+_extension/',
        ),
    ),
    BanRule(
        r'public (RefCounted)?BrowserStateKeyedServiceFactory',
        ('KeyedService factories in //ios/chrome/browser should inherit from',
         '(Refcounted)?ProfileKeyedServieFactoryIOS, not directory from',
         '(Refcounted)?BrowserStateKeyedServiceFactory.'),
        treat_as_error=True,
        excluded_paths=(
            'ios/components',
            'ios/web_view',
        ),
    ),
)

_BANNED_IOS_EGTEST_FUNCTIONS: Sequence[BanRule] = (BanRule(
    r'/\bEXPECT_OCMOCK_VERIFY\b',
    ('EXPECT_OCMOCK_VERIFY should not be used in EarlGrey tests because ',
     'it is meant for GTests. Use [mock verify] instead.'),
    True,
), )

_BANNED_CPP_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        '%#0',
        (
            'Zero-padded values that use "#" to add prefixes don\'t exhibit ',
            'consistent behavior, since the prefix is not prepended for zero ',
            'values. Use "0x%0..." instead.',
        ),
        False,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\busing namespace ',
        (
            'Using directives (\'using namespace x\') are banned by the Google Style',
            'Guide ( http://google.github.io/styleguide/cppguide.html#Namespaces ).',
            'Explicitly qualify symbols or use using declarations (\'using x::foo\').',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    # Make sure that gtest's FRIEND_TEST() macro is not used; the
    # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
    # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
    BanRule(
        'FRIEND_TEST(',
        (
            'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
            'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
        ),
        False,
        excluded_paths=(
            'base/gtest_prod_util.h',
            'base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/gtest_prod_util.h',
        ),
    ),
    BanRule(
        r'/HANDLE_EINTR\(.*close',
        ('HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file',
         'descriptor will be closed, and it is incorrect to retry the close.',
         'Either call close directly and ignore its return value, or wrap close',
         'in IGNORE_EINTR to use its return value. See http://crbug.com/269623'
         ),
        True,
        (),
    ),
    BanRule(
        r'/IGNORE_EINTR\((?!.*close)',
        (
            'IGNORE_EINTR is only valid when wrapping close. To wrap other system',
            'calls, use HANDLE_EINTR. See http://crbug.com/269623',
        ),
        True,
        (
            # Files that #define IGNORE_EINTR.
            r'^base/posix/eintr_wrapper\.h$',
            r'^ppapi/tests/test_broker\.cc$',
        ),
    ),
    BanRule(
        r'/v8::Extension\(',
        (
            'Do not introduce new v8::Extensions into the code base, use',
            'gin::Wrappable instead. See http://crbug.com/334679',
        ),
        True,
        (r'extensions/renderer/safe_builtins\.*', ),
    ),
    BanRule(
        '#pragma comment(lib,',
        ('Specify libraries to link with in build files and not in the source.',
         ),
        True,
        (
            r'^base/third_party/symbolize/.*',
            r'^third_party/abseil-cpp/.*',
            r'^third_party/grpc/source/.*',
        ),
    ),
    BanRule(
        r'/base::SequenceChecker\b',
        ('Consider using SEQUENCE_CHECKER macros instead of the class directly.',
         ),
        False,
        (),
    ),
    BanRule(
        r'/base::ThreadChecker\b',
        ('Consider using THREAD_CHECKER macros instead of the class directly.',
         ),
        False,
        (),
    ),
    BanRule(
        r'/\b(?!(Sequenced|SingleThread))\w*TaskRunner::(GetCurrentDefault|CurrentDefaultHandle)',
        (
            'It is not allowed to call these methods from the subclasses ',
            'of Sequenced or SingleThread task runners.',
        ),
        True,
        (),
    ),
    BanRule(
        r'/(Time(|Delta|Ticks)|ThreadTicks)::FromInternalValue|ToInternalValue',
        (
            'base::TimeXXX::FromInternalValue() and ToInternalValue() are',
            'deprecated (http://crbug.com/634507). Please avoid converting away',
            'from the Time types in Chromium code, especially if any math is',
            'being done on time values. For interfacing with platform/library',
            'APIs, use base::Time::(From,To)DeltaSinceWindowsEpoch() or',
            'base::{TimeDelta::In}Microseconds(), or one of the other type',
            'converter methods instead. For faking TimeXXX values (for unit',
            'testing only), use TimeXXX() + Microseconds(N). For',
            'other use cases, please contact base/time/OWNERS.',
        ),
        False,
        excluded_paths=(
            'base/time/time.h',
            'base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/time/time.h',
        ),
    ),
    BanRule(
        'CallJavascriptFunctionUnsafe',
        (
            'Don\'t use CallJavascriptFunctionUnsafe() in new code. Instead, use',
            'AllowJavascript(), OnJavascriptAllowed()/OnJavascriptDisallowed(),',
            'and CallJavascriptFunction(). See https://goo.gl/qivavq.',
        ),
        False,
        (
            r'^content/browser/webui/web_ui_impl\.(cc|h)$',
            r'^content/public/browser/web_ui\.h$',
            r'^content/public/test/test_web_ui\.(cc|h)$',
        ),
    ),
    BanRule(
        'leveldb::DB::Open',
        (
            'Instead of leveldb::DB::Open() use leveldb_env::OpenDB() from',
            'third_party/leveldatabase/env_chromium.h. It exposes databases to',
            "Chrome's tracing, making their memory usage visible.",
        ),
        True,
        (r'^third_party/leveldatabase/.*\.(cc|h)$', ),
    ),
    BanRule(
        'leveldb::NewMemEnv',
        (
            'Instead of leveldb::NewMemEnv() use leveldb_chrome::NewMemEnv() from',
            'third_party/leveldatabase/leveldb_chrome.h. It exposes environments',
            "to Chrome's tracing, making their memory usage visible.",
        ),
        True,
        (r'^third_party/leveldatabase/.*\.(cc|h)$', ),
    ),
    BanRule(
        'base::ScopedMockTimeMessageLoopTaskRunner',
        (
            'ScopedMockTimeMessageLoopTaskRunner is deprecated. Prefer',
            'TaskEnvironment::TimeSource::MOCK_TIME. There are still a',
            'few cases that may require a ScopedMockTimeMessageLoopTaskRunner',
            '(i.e. mocking the main MessageLoopForUI in browser_tests), but check',
            'with gab@ first if you think you need it)',
        ),
        False,
        (),
    ),
    BanRule(
        '\brand\b',
        (
            'Use base/rand_util.h instead of rand(). The result of rand() is',
            'based on a global random seed, which can be fully deterministic,',
            'instead of random, if called at a specific time during startup.',
        ),
        True,
        (),
    ),
    BanRule(
        '\bstd::aligned_(storage|union)\b',
        ('std::aligned_storage and std::aligned_union are deprecated in',
         'C++23. Use an aligned char array instead.'),
        True,
        (),
    ),
    BanRule(
        'std::regex',
        (
            'Using std::regex adds unnecessary binary size to Chrome. Please use',
            're2::RE2 instead (crbug.com/755321)',
        ),
        True,
        [
            # Only used to implement a test HTTP server:
            # https://crbug.com/438422635#comment8
            '^third_party/crashpad/crashpad/third_party/'
            r'cpp-httplib/cpp-httplib/httplib\.h$',
            # Abseil's benchmarks never linked into chrome.
            'third_party/abseil-cpp/.*_benchmark.cc',
        ],
    ),
    BanRule(
        r'/\bstd::sto(i|l|ul|ll|ull)\b',
        (
            'std::sto{i,l,ul,ll,ull}() use exceptions to communicate results. ',
            'Use base::StringTo[U]Int[64]() instead.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bstd::sto(f|d|ld)\b',
        (
            'std::sto{f,d,ld}() use exceptions to communicate results. ',
            'For locale-independent values, e.g. reading numbers from disk',
            'profiles, use base::StringToDouble().',
            'For user-visible values, parse using ICU.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bstd::to_string\b',
        (
            'std::to_string() is locale dependent and slower than alternatives.',
            'For locale-independent strings, e.g. writing numbers to disk',
            'profiles, use base::NumberToString().',
            'For user-visible strings, use base::FormatNumber() and',
            'the related functions in base/i18n/number_formatting.h.',
        ),
        True,
        [
            # TODO(crbug.com/335672557): Please do not add to this list. Existing
            # uses should removed.
            'third_party/blink/renderer/core/css/parser/css_proto_converter.cc',
            'third_party/blink/renderer/core/editing/ime/edit_context.cc',
            'third_party/blink/renderer/platform/graphics/bitmap_image_test.cc',
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        r'/#include <(cctype|ctype\.h|cwctype|wctype.h)>',
        (
            '<cctype>/<ctype.h>/<cwctype>/<wctype.h> are banned. Use',
            '"third_party/abseil-cpp/absl/strings/ascii.h" instead.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bstd::shared_ptr\b',
        ('std::shared_ptr is banned. Use scoped_refptr instead.', ),
        True,
        [
            # Needed for interop with third-party library.
            r'^third_party/blink/renderer/core/typed_arrays/array_buffer/' +
            r'array_buffer_contents\.(cc|h)',
            r'^third_party/blink/renderer/core/typed_arrays/dom_array_buffer\.cc',
            '^third_party/blink/renderer/bindings/core/v8/' +
            'v8_wasm_response_extensions.cc',
            r'^gin/array_buffer\.(cc|h)',
            r'^gin/per_isolate_data\.(cc|h)',
            '^chrome/services/sharing/nearby/',
            # Needed for interop with third-party library libunwindstack.
            r'^base/profiler/libunwindstack_unwinder_android\.(cc|h)',
            r'^base/profiler/native_unwinder_android_memory_regions_map_impl.(cc|h)',
            # Needed for interop with third-party boringssl cert verifier
            '^third_party/boringssl/',
            '^net/cert/',
            '^net/tools/cert_verify_tool/',
            '^services/cert_verifier/',
            '^components/certificate_transparency/',
            '^components/media_router/common/providers/cast/certificate/',
            '^components/trusted_vault/',
            # gRPC provides some C++ libraries that use std::shared_ptr<>.
            '^chromeos/ash/services/libassistant/grpc/',
            '^chromecast/cast_core/grpc',
            '^chromecast/cast_core/runtime/browser',
            r'^ios/chrome/test/earl_grey/chrome_egtest_plugin_client\.(mm|h)',
            # Fuchsia provides C++ libraries that use std::shared_ptr<>.
            r'^base/fuchsia/.*\.(cc|h)',
            r'.*fuchsia.*test\.(cc|h)',
            # Clang plugins have different build config.
            '^tools/clang/plugins/',
            # Needed for interop with Android native-only services.
            r'^content/app/android/javaless_child_process_service\.cc',
            _THIRD_PARTY_EXCEPT_BLINK
        ],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bstd::weak_ptr\b',
        ('std::weak_ptr is banned. Use base::WeakPtr instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\blong long\b',
        ('long long is banned. Use [u]int64_t instead.', ),
        False,  # Only a warning since it is already used.
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\b(absl|std)::any\b',
        (
            '{absl,std}::any are banned due to incompatibility with the component ',
            'build.',
        ),
        True,
        # Not an error in third party folders, though it probably should be :)
        [_THIRD_PARTY_EXCEPT_BLINK],
    ),
    BanRule(
        r'/\bstd::bind\b',
        (
            'std::bind() is banned because of lifetime risks. Use ',
            'base::Bind{Once,Repeating}() instead.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        (r'/\bstd::(?:'
         r'linear_congruential_engine|mersenne_twister_engine|'
         r'subtract_with_carry_engine|discard_block_engine|'
         r'independent_bits_engine|shuffle_order_engine|'
         r'minstd_rand0?|mt19937(_64)?|ranlux(24|48)(_base)?|knuth_b|'
         r'default_random_engine|'
         r'random_device|'
         r'seed_seq'
         r')\b'),
        (
            'STL random number engines and generators are banned. Use the ',
            'helpers in base/rand_util.h instead, e.g. base::RandBytes() or ',
            'base::RandomBitGenerator.'
            '',
            'Please reach out to cxx@chromium.org if the base APIs are ',
            'insufficient for your needs.',
        ),
        True,
        [
            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
            # Various tools which build outside of Chrome.
            r'testing/libfuzzer',
            r'testing/perf/confidence',
            r'tools/android/io_benchmark/',
            # Fuzzers are allowed to use standard library random number generators
            # since fuzzing speed + reproducibility is important.
            r'.+_fuzzer\.cc$',
            r'.+_fuzzertest\.cc$',
            # TODO(https://crbug.com/1380528): These are all unsanctioned uses of
            # the standard library's random number generators, and should be
            # migrated to the //base equivalent.
            r'ash/ambient/model/ambient_topic_queue\.cc',
            r'base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest\.cc',
            r'base/test/launcher/test_launcher\.cc',
            r'cc/metrics/video_playback_roughness_reporter_unittest\.cc',
            r'chrome/browser/apps/app_service/metrics/website_metrics\.cc',
            r'chrome/browser/ash/power/auto_screen_brightness/monotone_cubic_spline_unittest\.cc',
            r'chrome/browser/ash/printing/zeroconf_printer_detector_unittest\.cc',
            r'chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest\.cc',
            r'chrome/browser/nearby_sharing/contacts/nearby_share_contacts_sorter_unittest\.cc',
            r'chrome/browser/privacy_budget/mesa_distribution_unittest\.cc',
            r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
            r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
            r'chrome/browser/win/conflicts/module_blocklist_cache_util_unittest\.cc',
            r'chromeos/ash/components/memory/userspace_swap/swap_storage_unittest\.cc',
            r'chromeos/ash/components/memory/userspace_swap/userspace_swap\.cc',
            r'components/metrics/metrics_state_manager\.cc',
            r'components/omnibox/browser/history_quick_provider_performance_unittest\.cc',
            r'components/zucchini/disassembler_elf_unittest\.cc',
            r'content/browser/webid/federated_auth_request_impl\.cc',
            r'content/browser/webid/federated_auth_request_impl\.cc',
            r'media/cast/test/utility/udp_proxy\.h',
            r'sql/recover_module/module_unittest\.cc',
            r'components/regional_capabilities/regional_capabilities_utils.cc',
            # Do not add new entries to this list. If you have a use case which is
            # not satisfied by the current APIs (i.e. you need an explicitly-seeded
            # sequence, or stability of some sort is required), please contact
            # cxx@chromium.org.
        ],
    ),
    BanRule(
        r'/\b(absl,std)::bind_front\b',
        ('{absl,std}::bind_front() are banned. Use base::Bind{Once,Repeating}() '
         'instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bABSL_FLAG\b',
        ('ABSL_FLAG is banned. Use base::CommandLine instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\babsl::c_',
        ('Abseil container utilities are banned. Use std::ranges:: instead.',
         ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\babsl::FixedArray\b',
        ('absl::FixedArray is banned. Use base::FixedArray instead.', ),
        True,
        [
            # base::FixedArray provides canonical access.
            r'^base/types/fixed_array.h',
            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
        ],
    ),
    BanRule(
        r'/\babsl::FunctionRef\b',
        ('absl::FunctionRef is banned. Use base::FunctionRef instead.', ),
        True,
        [
            # base::Bind{Once,Repeating} references absl::FunctionRef to disallow
            # interoperability.
            r'^base/functional/bind_internal\.h',
            # base::FunctionRef is implemented on top of absl::FunctionRef.
            r'^base/functional/function_ref.*\..+',
            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
        ],
    ),
    BanRule(
        r'/\babsl::(Insecure)?BitGen\b',
        ('absl random number generators are banned. Use the helpers in '
         'base/rand_util.h instead, e.g. base::RandBytes() or ',
         'base::RandomBitGenerator.'),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        pattern=r'/\babsl::(optional|nullopt|make_optional)\b',
        explanation=('absl::optional is banned. Use std::optional instead.', ),
        treat_as_error=True,
        excluded_paths=[
            _THIRD_PARTY_EXCEPT_BLINK,
        ]),
    BanRule(
        r'/(\babsl::Span\b|#include <span>|\bstd::span\b)',
        ('absl::Span and std::span are banned. Use base::span instead.', ),
        True,
        [
            # Included for conversions between base and std.
            r'base/containers/span.h',
            # Test base::span<> compatibility against std::span<>.
            r'base/containers/span_unittest.cc',
            # //base/numerics can't use base or absl. So it uses std.
            r'base/numerics/.*'

            # Needed to use QUICHE API.
            r'android_webview/browser/ip_protection/.*',
            r'chrome/browser/ip_protection/.*',
            r'components/ip_protection/.*',
            r'net/third_party/quiche/overrides/quiche_platform_impl/quiche_stack_trace_impl\.*',
            r'services/network/web_transport\.cc',

            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
        ],
    ),
    BanRule(
        r'/\babsl::StatusOr\b',
        ('absl::StatusOr is banned. Use base::expected instead.', ),
        True,
        [
            # Needed to use liburlpattern API.
            r'components/url_pattern/.*',
            r'services/network/shared_dictionary/simple_url_pattern_matcher\.cc',
            r'third_party/blink/renderer/core/url_pattern/.*',
            r'third_party/blink/renderer/modules/manifest/manifest_parser\.cc',

            # Needed to use QUICHE API.
            r'android_webview/browser/ip_protection/.*',
            r'chrome/browser/ip_protection/.*',
            r'components/ip_protection/.*',
            r'net/quic/dedicated_web_transport_http3_client\.cc',

            # Needed to use MediaPipe API.
            r'components/media_effects/.*\.cc',
            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        r'/\babsl::(StrSplit|StrJoin|StrCat|StrAppend|Substitute|StrContains)\b',
        ('Abseil string utilities are banned. Use base/strings instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\babsl::(Mutex|CondVar|Notification|Barrier|BlockingCounter)\b',
        (
            'Abseil synchronization primitives are banned. Use',
            'base/synchronization instead.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\babsl::(Duration|Time|TimeZone|CivilDay)\b',
        ('Abseil\'s time library is banned. Use base/time instead.', ),
        True,
        [
            # Needed to use QUICHE API.
            r'android_webview/browser/ip_protection/.*',
            r'chrome/browser/ip_protection/.*',
            r'components/ip_protection/.*',

            # Needed to integrate with //third_party/nearby
            r'chrome/services/sharing/nearby/platform/input_file.cc',
            r'chrome/services/sharing/nearby/platform/input_file.h',
            r'chrome/services/sharing/nearby/platform/output_file.cc',
            r'chrome/services/sharing/nearby/platform/output_file.h',
            r'components/cross_device/nearby/system_clock.cc',
            _THIRD_PARTY_EXCEPT_BLINK  # Not an error in third_party folders.
        ],
    ),
    BanRule(
        r'/absl::(bad_variant_access|get|holds_alternative|monostate|variant|'
        r'visit)',
        ('Abseil\'s variant library is banned, use std.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],
    ),
    BanRule(
        r'/absl::(apply|exchange|forward|in_place|index_sequence|'
        r'integer_sequence|make_from_tuple|make_index_sequence|'
        r'make_integer_sequence|move)',
        ('Abseil\'s util library is banned, use std.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],
    ),
    BanRule(
        r'/#include <chrono>',
        ('<chrono> is banned. Use base/time instead.', ),
        True,
        [
            # Not an error in third_party folders:
            _THIRD_PARTY_EXCEPT_BLINK,
            # This uses openscreen API depending on std::chrono.
            'components/openscreen_platform/task_runner.cc',
        ]),
    BanRule(
        r'/#include <exception>',
        ('Exceptions are banned and disabled in Chromium.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bstd::function\b',
        ('std::function is banned. Use base::{Once,Repeating}Callback instead.',
         ),
        True,
        [
            # Has tests that template trait helpers don't unintentionally match
            # std::function.
            r'base/functional/callback_helpers_unittest\.cc',
            # Required to implement interfaces from the third-party perfetto
            # library.
            r'base/tracing/perfetto_task_runner\.cc',
            r'base/tracing/perfetto_task_runner\.h',
            # Needed for interop with the third-party nearby library type
            # location::nearby::connections::ResultCallback.
            r'chrome/services/sharing/nearby/nearby_connections_conversions\.cc'
            # Needed for interop with the internal libassistant library.
            r'chromeos/ash/services/libassistant/callback_utils\.h',
            # Needed for interop with Fuchsia fidl APIs.
            r'fuchsia_web/webengine/browser/context_impl_browsertest\.cc',
            r'fuchsia_web/webengine/browser/cookie_manager_impl_unittest\.cc',
            r'fuchsia_web/webengine/browser/media_player_impl_unittest\.cc',
            # Required to interop with interfaces from the third-party ChromeML
            # library API.
            r'services/on_device_model/ml/chrome_ml_api\.h',
            r'services/on_device_model/ml/on_device_model_executor\.cc',
            r'services/on_device_model/ml/on_device_model_executor\.h',
            # Required to interop with interfaces from the third-party perfetto
            # library.
            r'components/tracing/common/etw_consumer_win_unittest\.cc',
            r'components/tracing/common/etw_system_data_source_win\.cc',
            r'components/tracing/common/etw_consumer_win\.h',
            r'components/tracing/common/etw_consumer_win\.cc',
            r'services/tracing/public/cpp/perfetto/custom_event_recorder\.cc',
            r'services/tracing/public/cpp/perfetto/perfetto_traced_process\.cc',
            r'services/tracing/public/cpp/perfetto/perfetto_traced_process\.h',
            r'services/tracing/public/cpp/perfetto/perfetto_tracing_backend\.cc',
            r'services/tracing/public/cpp/perfetto/producer_client\.cc',
            r'services/tracing/public/cpp/perfetto/producer_client\.h',
            r'services/tracing/public/cpp/perfetto/producer_test_utils\.cc',
            r'services/tracing/public/cpp/perfetto/producer_test_utils\.h',
            # Required for interop with the third-party webrtc library.
            r'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.cc',
            r'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.h',
            # TODO(https://crbug.com/1364577): Various uses that should be
            # migrated to something else.
            # Should use base::OnceCallback or base::RepeatingCallback.
            r'base/allocator/dispatcher/initializer_unittest\.cc',
            r'chrome/browser/ash/accessibility/speech_monitor\.cc',
            r'chrome/browser/ash/accessibility/speech_monitor\.h',
            r'chrome/browser/ash/login/ash_hud_login_browsertest\.cc',
            r'chromecast/base/observer_unittest\.cc',
            r'chromecast/browser/cast_web_view\.h',
            r'chromecast/public/cast_media_shlib\.h',
            r'device/bluetooth/floss/exported_callback_manager\.h',
            r'device/bluetooth/floss/floss_dbus_client\.h',
            r'device/fido/cable/v2_handshake_unittest\.cc',
            r'device/fido/pin\.cc',
            r'services/tracing/perfetto/test_utils\.h',
            # Should use base::FunctionRef.
            r'chrome/browser/media/webrtc/test_stats_dictionary\.cc',
            r'chrome/browser/media/webrtc/test_stats_dictionary\.h',
            r'chromeos/ash/services/libassistant/device_settings_controller\.cc',
            r'components/browser_ui/client_certificate/android/ssl_client_certificate_request\.cc',
            r'components/gwp_asan/client/sampling_malloc_shims_unittest\.cc',
            r'content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest\.cc',
            # Does not need std::function at all.
            r'components/omnibox/browser/autocomplete_result\.cc',
            r'device/fido/win/webauthn_api\.cc',
            r'media/audio/alsa/alsa_util\.cc',
            r'media/remoting/stream_provider\.h',
            r'sql/vfs_wrapper\.cc',
            # TODO(https://crbug.com/1364585): Remove usage and exception list
            # entries.
            r'extensions/renderer/api/automation/automation_internal_custom_bindings\.cc',
            r'extensions/renderer/api/automation/automation_internal_custom_bindings\.h',
            # TODO(https://crbug.com/1364579): Remove usage and exception list
            # entry.
            r'ui/views/controls/focus_ring\.h',

            # Various pre-existing uses in //tools that is low-priority to fix.
            r'tools/binary_size/libsupersize/viewer/caspian/diff\.cc',
            r'tools/binary_size/libsupersize/viewer/caspian/model\.cc',
            r'tools/binary_size/libsupersize/viewer/caspian/model\.h',
            r'tools/binary_size/libsupersize/viewer/caspian/tree_builder\.h',
            r'tools/clang/base_bind_rewriters/BaseBindRewriters\.cpp',

            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        r'/#include <X11/',
        ('Do not use Xlib. Use xproto (from //ui/gfx/x:xproto) instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bstd::ratio\b',
        ('std::ratio is banned by the Google Style Guide.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/\bstd::aligned_alloc\b',
        (
            'std::aligned_alloc() is not yet allowed (crbug.com/1412818). Use ',
            'base::AlignedAlloc() instead.',
        ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/#include <(barrier|latch|semaphore|stop_token)>',
        ('The thread support library is banned. Use base/synchronization '
         'instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bstd::execution::(par|seq)\b',
        ('std::execution::(par|seq) is banned; they do not fit into '
         ' Chrome\'s threading model, and libc++ doesn\'t have full '
         'support.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],
    ),
    BanRule(
        r'/\bstd::bit_cast\b',
        ('std::bit_cast is banned; use base::bit_cast instead for values and '
         'standard C++ casting when pointers are involved.', ),
        True,
        [
            # Don't warn in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
            # //base/numerics can't use base or absl.
            r'base/numerics/.*'
        ],
    ),
    BanRule(
        r'/\bstd::(c8rtomb|mbrtoc8)\b',
        ('std::c8rtomb() and std::mbrtoc8() are banned.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bchar8_t|std::u8string\b',
        (
            'char8_t and std::u8string are not yet allowed. Can you use [unsigned]',
            ' char and std::string instead?',
        ),
        True,
        [
            # The demangler does not use this type but needs to know about it.
            r'base/third_party/symbolize/demangle\.cc',
            # Don't warn in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        r'/(\b(co_await|co_return|co_yield)\b|#include <coroutine>)',
        ('Coroutines are not yet allowed (https://crbug.com/1403840).', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/^\s*(export\s|import\s+["<:\w]|module(;|\s+[:\w]))',
        ('Modules are disallowed for now due to lack of toolchain support.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\[\[(\w*::)?no_unique_address\]\]',
        (
            '[[no_unique_address]] does not work as expected on Windows ',
            '(https://crbug.com/1414621). Use NO_UNIQUE_ADDRESS instead.',
        ),
        True,
        [
            # NO_UNIQUE_ADDRESS / PA_NO_UNIQUE_ADDRESS provide canonical access.
            r'^base/compiler_specific\.h',
            r'^base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/compiler_specific\.h',
            # Not an error in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK,
        ],
    ),
    BanRule(
        r'/#include <format>',
        ('<format> is not yet allowed. Use base::StringPrintf() instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        pattern='std::views',
        explanation=('Use of std::views is banned in Chrome. If you need this '
                     'functionality, please contact cxx@chromium.org.', ),
        treat_as_error=True,
        excluded_paths=[
            # Don't warn in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        # Ban everything except specifically allowlisted constructs.
        pattern=r'/std::ranges::(?!(?:' + '|'.join((
            # From https://en.cppreference.com/w/cpp/ranges:
            # Range access
            'begin',
            'end',
            'cbegin',
            'cend',
            'rbegin',
            'rend',
            'crbegin',
            'crend',
            'size',
            'ssize',
            'empty',
            'data',
            'cdata',
            # Range primitives
            'iterator_t',
            'const_iterator_t',
            'sentinel_t',
            'const_sentinel_t',
            'range_difference_t',
            'range_size_t',
            'range_value_t',
            'range_reference_t',
            'range_const_reference_t',
            'range_rvalue_reference_t',
            'range_common_reference_t',
            # Dangling iterator handling
            'dangling',
            'borrowed_iterator_t',
            # Banned: borrowed_subrange_t
            # Range concepts
            'range',
            'borrowed_range',
            'sized_range',
            'view',
            'input_range',
            'output_range',
            'forward_range',
            'bidirectional_range',
            'random_access_range',
            'contiguous_range',
            'common_range',
            'viewable_range',
            'constant_range',
            # Views
            'subrange',
            'subrange_kind',
            # Banned: Range factories
            # Banned: Range adaptors
            # Incidentally listed on
            # https://en.cppreference.com/w/cpp/header/ranges:
            'enable_borrowed_range',
            'enable_view',
            # From https://en.cppreference.com/w/cpp/algorithm/ranges:
            # Constrained algorithms: non-modifying sequence operations
            'all_of',
            'any_of',
            'none_of',
            'for_each',
            'for_each_n',
            'count',
            'count_if',
            'mismatch',
            'equal',
            'lexicographical_compare',
            'find',
            'find_if',
            'find_if_not',
            'find_end',
            'find_first_of',
            'adjacent_find',
            'search',
            'search_n',
            # Constrained algorithms: modifying sequence operations
            'copy',
            'copy_if',
            'copy_n',
            'copy_backward',
            'move',
            'move_backward',
            'fill',
            'fill_n',
            'transform',
            'generate',
            'generate_n',
            'remove',
            'remove_if',
            'remove_copy',
            'remove_copy_if',
            'replace',
            'replace_if',
            'replace_copy',
            'replace_copy_if',
            'swap_ranges',
            'reverse',
            'reverse_copy',
            'rotate',
            'rotate_copy',
            'shuffle',
            'sample',
            'unique',
            'unique_copy',
            # Constrained algorithms: partitioning operations
            'is_partitioned',
            'partition',
            'partition_copy',
            'stable_partition',
            'partition_point',
            # Constrained algorithms: sorting operations
            'is_sorted',
            'is_sorted_until',
            'sort',
            'partial_sort',
            'partial_sort_copy',
            'stable_sort',
            'nth_element',
            # Constrained algorithms: binary search operations (on sorted ranges)
            'lower_bound',
            'upper_bound',
            'binary_search',
            'equal_range',
            # Constrained algorithms: set operations (on sorted ranges)
            'merge',
            'inplace_merge',
            'includes',
            'set_difference',
            'set_intersection',
            'set_symmetric_difference',
            'set_union',
            # Constrained algorithms: heap operations
            'is_heap',
            'is_heap_until',
            'make_heap',
            'push_heap',
            'pop_heap',
            'sort_heap',
            # Constrained algorithms: minimum/maximum operations
            'max',
            'max_element',
            'min',
            'min_element',
            'minmax',
            'minmax_element',
            'clamp',
            # Constrained algorithms: permutation operations
            'is_permutation',
            'next_permutation',
            'prev_premutation',
            # Constrained uninitialized memory algorithms
            'uninitialized_copy',
            'uninitialized_copy_n',
            'uninitialized_fill',
            'uninitialized_fill_n',
            'uninitialized_move',
            'uninitialized_move_n',
            'uninitialized_default_construct',
            'uninitialized_default_construct_n',
            'uninitialized_value_construct',
            'uninitialized_value_construct_n',
            'destroy',
            'destroy_n',
            'destroy_at',
            'construct_at',
            # Return types
            'in_fun_result',
            'in_in_result',
            'in_out_result',
            'in_in_out_result',
            'in_out_out_result',
            'min_max_result',
            'in_found_result',
            # From https://en.cppreference.com/w/cpp/header/functional
            'equal_to',
            'not_equal_to',
            'greater',
            'less',
            'greater_equal',
            'less_equal',
            # From https://en.cppreference.com/w/cpp/iterator
            'advance',
            'distance',
            'next',
            'prev',
            # Require a word boundary at the end of negative lookahead
            # assertion, e.g. to ensure that even though `view` is allowed (and
            # should not match this regex), `views` is still treated as
            # disallowed (and matches the regex).
        )) + r')\b)\w+',
        explanation=(
            'Use of range views and associated helpers is banned in Chrome. '
            'If you need this functionality, please contact cxx@chromium.org.',
        ),
        treat_as_error=True,
        excluded_paths=[
            # Don't warn in third_party folders.
            _THIRD_PARTY_EXCEPT_BLINK
        ],
    ),
    BanRule(
        r'/#include <regex>',
        ('<regex> is not allowed. Use third_party/re2 instead.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/#include <source_location>',
        ('<source_location> is not yet allowed. Use base/location.h instead.',
         ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bstd::to_address\b',
        (
            'std::to_address is banned because it is not guaranteed to be',
            'SFINAE-compatible. Use base::to_address from base/types/to_address.h',
            'instead.',
        ),
        True,
        [
            # Needed in base::to_address implementation.
            r'base/types/to_address.h',
            _THIRD_PARTY_EXCEPT_BLINK
        ],  # Not an error in third_party folders.
    ),
    BanRule(
        r'/#include <syncstream>',
        ('<syncstream> is banned.', ),
        True,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Don't warn in third_party folders.
    ),
    BanRule(
        r'/\bRunMessageLoop\b',
        ('RunMessageLoop is deprecated, use RunLoop instead.', ),
        False,
        (),
    ),
    BanRule(
        'RunAllPendingInMessageLoop()',
        (
            'Prefer RunLoop over RunAllPendingInMessageLoop, please contact gab@',
            "if you're convinced you need this.",
        ),
        False,
        (),
    ),
    BanRule(
        'RunAllPendingInMessageLoop(BrowserThread',
        (
            'RunAllPendingInMessageLoop is deprecated. Use RunLoop for',
            'BrowserThread::UI, BrowserTaskEnvironment::RunIOThreadUntilIdle',
            'for BrowserThread::IO, and prefer RunLoop::QuitClosure to observe',
            'async events instead of flushing threads.',
        ),
        False,
        (),
    ),
    BanRule(
        r'MessageLoopRunner',
        ('MessageLoopRunner is deprecated, use RunLoop instead.', ),
        False,
        (),
    ),
    BanRule(
        'GetDeferredQuitTaskForRunLoop',
        (
            "GetDeferredQuitTaskForRunLoop shouldn't be needed, please contact",
            'gab@ if you found a use case where this is the only solution.',
        ),
        False,
        (),
    ),
    BanRule(
        'sqlite3_initialize(',
        (
            'Instead of calling sqlite3_initialize(), depend on //sql, ',
            '#include "sql/initialize.h" and use sql::EnsureSqliteInitialized().',
        ),
        True,
        (
            r'^sql/initialization\.(cc|h)$',
            r'^third_party/sqlite/.*\.(c|cc|h)$',
        ),
    ),
    BanRule(
        'CREATE VIEW',
        (
            'SQL views are disabled in Chromium feature code',
            'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-views',
        ),
        True,
        (
            _THIRD_PARTY_EXCEPT_BLINK,
            # sql/ itself uses views when using memory-mapped IO.
            r'^sql/.*',
            # Various performance tools that do not build as part of Chrome.
            r'^infra/.*',
            r'^tools/perf.*',
            r'.*perfetto.*',
        ),
    ),
    BanRule(
        'CREATE VIRTUAL TABLE',
        (
            'SQL virtual tables are disabled in Chromium feature code',
            'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-virtual-tables',
        ),
        True,
        (
            _THIRD_PARTY_EXCEPT_BLINK,
            # sql/ itself uses virtual tables in the recovery module and tests.
            r'^sql/.*',
            # Various performance tools that do not build as part of Chrome.
            r'^tools/perf.*',
            r'.*perfetto.*',
        ),
    ),
    BanRule(
        'std::random_shuffle',
        ('std::random_shuffle is deprecated in C++14, and removed in C++17. Use',
         'base::RandomShuffle instead.'),
        True,
        (),
    ),
    BanRule(
        'ios/web/public/test/http_server',
        ('web::HTTPserver is deprecated use net::EmbeddedTestServer instead.',
         ),
        False,
        (),
    ),
    BanRule(
        'GetAddressOf',
        ('Improper use of Microsoft::WRL::ComPtr<T>::GetAddressOf() has been ',
         'implicated in a few leaks. ReleaseAndGetAddressOf() is safe but ',
         'operator& is generally recommended. So always use operator& instead. ',
         'See http://crbug.com/914910 for more conversion guidance.'),
        True,
        (),
    ),
    BanRule(
        'SHFileOperation',
        ('SHFileOperation was deprecated in Windows Vista, and there are less ',
         'complex functions to achieve the same goals. Use IFileOperation for ',
         'any esoteric actions instead.'),
        True,
        (),
    ),
    BanRule(
        'StringFromGUID2',
        ('StringFromGUID2 introduces an unnecessary dependency on ole32.dll.',
         'Use base::win::WStringFromGUID instead.'),
        True,
        (r'/base/win/win_util_unittest.cc', ),
    ),
    BanRule(
        'StringFromCLSID',
        ('StringFromCLSID introduces an unnecessary dependency on ole32.dll.',
         'Use base::win::WStringFromGUID instead.'),
        True,
        (r'/base/win/win_util_unittest.cc', ),
    ),
    BanRule(
        'kCFAllocatorNull',
        (
            'The use of kCFAllocatorNull with the NoCopy creation of ',
            'CoreFoundation types is prohibited.',
        ),
        True,
        (),
    ),
    BanRule(
        'mojo::ConvertTo',
        ('mojo::ConvertTo and TypeConverter are deprecated. Please consider',
         'StructTraits / UnionTraits / EnumTraits / ArrayTraits / MapTraits /',
         'StringTraits if you would like to convert between custom types and',
         'the wire format of mojom types.'),
        False,
        (
            r'^fuchsia_web/webengine/browser/url_request_rewrite_rules_manager\.cc$',
            r'^fuchsia_web/webengine/url_request_rewrite_type_converters\.cc$',
            r'^third_party/blink/.*\.(cc|h)$',
            r'^content/renderer/.*\.(cc|h)$',
        ),
    ),
    BanRule(
        'GetInterfaceProvider',
        ('InterfaceProvider is deprecated.',
         'Please use ExecutionContext::GetBrowserInterfaceBroker and overrides',
         'or Platform::GetBrowserInterfaceBroker.'),
        False,
        (),
    ),
    BanRule(
        'CComPtr',
        ('New code should use Microsoft::WRL::ComPtr from wrl/client.h as a ',
         'replacement for CComPtr from ATL. See http://crbug.com/5027 for more ',
         'details.'),
        False,
        (),
    ),
    BanRule(
        r'/\b(IFACE|STD)METHOD_?\(',
        ('IFACEMETHOD() and STDMETHOD() make code harder to format and read.',
         'Instead, always use IFACEMETHODIMP in the declaration.'),
        False,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(
        'RemoveAllChildViewsWithoutDeleting',
        ('RemoveAllChildViewsWithoutDeleting is deprecated.',
         'This method is deemed dangerous as, unless raw pointers are re-added,',
         'calls to this method introduce memory leaks.'),
        False,
        (),
    ),
    BanRule(
        r'/\bTRACE_EVENT(_NESTABLE)?_ASYNC_',
        (
            'Please use TRACE_EVENT_BEGIN/END/INSTANT macros instead',
            'of TRACE_EVENT_ASYNC_.. and TRACE_EVENT_NESTABLE_ASYNC_... (crbug.com/432427382).',
        ),
        False,
        (
            r'^base/trace_event/.*',
            r'^base/tracing/.*',
        ),
    ),
    BanRule(
        'RoInitialize',
        ('Improper use of [base::win]::RoInitialize() has been implicated in a ',
         'few COM initialization leaks. Use base::win::ScopedWinrtInitializer ',
         'instead. See http://crbug.com/1197722 for more information.'),
        True,
        (
            r'^base/win/scoped_winrt_initializer\.cc$',
            r'^third_party/abseil-cpp/absl/.*',
        ),
    ),
    BanRule(
        r'base::Watchdog',
        (
            'base::Watchdog is deprecated because it creates its own thread.',
            'Instead, manually start a timer on a SequencedTaskRunner.',
        ),
        False,
        (),
    ),
    BanRule(
        'base::Passed',
        ('Do not use base::Passed. It is a legacy helper for capturing ',
         'move-only types with base::BindRepeating, but invoking the ',
         'resulting RepeatingCallback moves the captured value out of ',
         'the callback storage, and subsequent invocations may pass the ',
         'value in a valid but undefined state. Prefer base::BindOnce().',
         'See http://crbug.com/1326449 for context.'),
        False,
        (
            # False positive, but it is also fine to let bind internals reference
            # base::Passed.
            r'^base[\\/]functional[\\/]bind\.h',
            r'^base[\\/]functional[\\/]bind_internal\.h',
        ),
    ),
    BanRule(
        r'base::Feature k',
        ('Please use BASE_DECLARE_FEATURE() or BASE_FEATURE() instead of ',
         'directly declaring/defining features.'),
        True,
        [
            # Implements BASE_DECLARE_FEATURE().
            r'^base/feature_list\.h',
        ],
    ),
    BanRule(
        r'/\bchartorune\b',
        ('chartorune is not memory-safe, unless you can guarantee the input ',
         'string is always null-terminated. Otherwise, please use charntorune ',
         'from libphonenumber instead.'),
        True,
        [
            _THIRD_PARTY_EXCEPT_BLINK,
            # Exceptions to this rule should have a fuzzer.
        ],
    ),
    BanRule(
        r'/\b#include "base/atomicops\.h"\b',
        ('Do not use base::subtle atomics, but std::atomic, which are simpler '
         'to use, have better understood, clearer and richer semantics, and are '
         'harder to mis-use. See details in base/atomicops.h.', ),
        False,
        [_THIRD_PARTY_EXCEPT_BLINK],  # Not an error in third_party folders.
    ),
    BanRule(r'CrossThreadPersistent<', (
        'Do not use blink::CrossThreadPersistent, but '
        'blink::CrossThreadHandle. It is harder to mis-use.', 'More info: '
        'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs',
        'Please contact platform-architecture-dev@ before adding new instances.'
    ), False, []),
    BanRule(r'CrossThreadWeakPersistent<', (
        'Do not use blink::CrossThreadWeakPersistent, but '
        'blink::CrossThreadWeakHandle. It is harder to mis-use.', 'More info: '
        'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs',
        'Please contact platform-architecture-dev@ before adding new instances.'
    ), False, []),
    BanRule(r'objc/objc.h', (
        'Do not include <objc/objc.h>. It defines away ARC lifetime '
        'annotations, and is thus dangerous.',
        'Please use the pimpl pattern; search for `ObjCStorage` for examples.',
        'For further reading on how to safely mix C++ and Obj-C, see',
        'https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md'
    ), True, []),
    BanRule(
        r'/#include <filesystem>',
        ('libc++ <filesystem> is banned per the Google C++ styleguide.', ),
        True,
        # This fuzzing framework is a standalone open source project and
        # cannot rely on Chromium base.
        (r'third_party/centipede'),
    ),
    BanRule(
        r'TopDocument()',
        ('TopDocument() does not work correctly with out-of-process iframes. '
         'Please do not introduce new uses.', ),
        True,
        (
            # TODO(crbug.com/617677): Remove all remaining uses.
            r'^third_party/blink/renderer/core/dom/document\.cc',
            r'^third_party/blink/renderer/core/dom/document\.h',
            r'^third_party/blink/renderer/core/dom/element\.cc',
            r'^third_party/blink/renderer/core/exported/web_disallow_transition_scope_test\.cc',
            r'^third_party/blink/renderer/core/exported/web_document_test\.cc',
            r'^third_party/blink/renderer/core/html/html_anchor_element\.cc',
            r'^third_party/blink/renderer/core/html/html_dialog_element\.cc',
            r'^third_party/blink/renderer/core/html/html_element\.cc',
            r'^third_party/blink/renderer/core/html/html_frame_owner_element\.cc',
            r'^third_party/blink/renderer/core/html/media/video_wake_lock\.cc',
            r'^third_party/blink/renderer/core/loader/anchor_element_interaction_tracker\.cc',
            r'^third_party/blink/renderer/core/page/scrolling/root_scroller_controller\.cc',
            r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.cc',
            r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.h',
            r'^third_party/blink/renderer/core/script/classic_pending_script\.cc',
            r'^third_party/blink/renderer/core/script/script_loader\.cc',
        ),
    ),
    BanRule(
        pattern=r'base::raw_ptr<',
        explanation=('Do not use base::raw_ptr, use raw_ptr.', ),
        treat_as_error=True,
        excluded_paths=(
            '^base/',
            '^tools/',
        ),
    ),
    BanRule(
        pattern=r'base:raw_ref<',
        explanation=('Do not use base::raw_ref, use raw_ref.', ),
        treat_as_error=True,
        excluded_paths=(
            '^base/',
            '^tools/',
        ),
    ),
    BanRule(
        pattern=r'/raw_ptr<[^;}]*\w{};',
        explanation=(
            'Do not use {} for raw_ptr initialization, use = nullptr instead.',
        ),
        treat_as_error=True,
        excluded_paths=(
            '^base/',
            '^tools/',
        ),
    ),
    BanRule(
        pattern=r'/#include "base/allocator/.*/raw_'
        r'(ptr|ptr_cast|ptr_exclusion|ref).h"',
        explanation=(
            'Please include the corresponding facade headers:',
            '- #include "base/memory/raw_ptr.h"',
            '- #include "base/memory/raw_ptr_cast.h"',
            '- #include "base/memory/raw_ptr_exclusion.h"',
            '- #include "base/memory/raw_ref.h"',
        ),
        treat_as_error=True,
        excluded_paths=(
            '^base/',
            '^tools/',
        ),
    ),
    BanRule(
        pattern=r'ContentSettingsType::COOKIES',
        explanation=
        ('Do not use ContentSettingsType::COOKIES to check whether cookies are '
         'supported in the provided context. Instead rely on the '
         'content_settings::CookieSettings API. If you are using '
         'ContentSettingsType::COOKIES to check the user preference setting '
         'specifically, disregard this warning.', ),
        treat_as_error=False,
        excluded_paths=(
            '^chrome/browser/ui/content_settings/',
            '^components/content_settings/',
            '^services/network/cookie_settings.cc',
            '.*test.cc',
        ),
    ),
    BanRule(
        pattern=r'ContentSettingsType::TRACKING_PROTECTION',
        explanation=
        ('Do not directly use ContentSettingsType::TRACKING_PROTECTION to check '
         'for tracking protection exceptions. Instead rely on the '
         'privacy_sandbox::TrackingProtectionSettings API.', ),
        treat_as_error=False,
        excluded_paths=(
            '^chrome/browser/ui/content_settings/',
            '^components/content_settings/',
            '^components/privacy_sandbox/tracking_protection_settings.cc',
            '.*test.cc',
        ),
    ),
    BanRule(
        pattern=r'/\bg_signal_connect',
        explanation=('Use ScopedGSignal instead of g_signal_connect*()', ),
        treat_as_error=True,
        excluded_paths=('^ui/base/glib/scoped_gsignal.h', ),
    ),
    BanRule(
        pattern=r'features::kIsolatedWebApps',
        explanation=(
            'Do not use `features::kIsolatedWebApps` directly to guard Isolated ',
            'Web App code. ',
            'Use `content::AreIsolatedWebAppsEnabled()` in the browser process '
            'or check the `kEnableIsolatedWebAppsInRenderer` command line flag '
            'in the renderer process.',
        ),
        treat_as_error=True,
        excluded_paths=_TEST_CODE_EXCLUDED_PATHS + (
            '^chrome/browser/about_flags.cc',
            '^chrome/browser/component_updater/iwa_key_distribution_component_installer.cc',
            '^chrome/browser/web_applications/isolated_web_apps/chrome_content_browser_client_isolated_web_apps_part.cc',
            '^chrome/browser/ui/startup/bad_flags_prompt.cc',
            '^content/shell/browser/shell_content_browser_client.cc',
        )),
    BanRule(
        pattern=r'features::kIsolatedWebAppDevMode',
        explanation=(
            'Do not use `features::kIsolatedWebAppDevMode` directly to guard code ',
            'related to Isolated Web App Developer Mode. ',
            'Use `web_app::IsIwaDevModeEnabled()` instead.',
        ),
        treat_as_error=True,
        excluded_paths=_TEST_CODE_EXCLUDED_PATHS + (
            '^chrome/browser/about_flags.cc',
            '^chrome/browser/web_applications/isolated_web_apps/isolated_web_app_features.cc',
            '^chrome/browser/ui/startup/bad_flags_prompt.cc',
        )),
    BanRule(
        pattern=r'features::kIsolatedWebAppUnmanagedInstall',
        explanation=(
            'Do not use `features::kIsolatedWebAppUnmanagedInstall` directly to ',
            'guard code related to unmanaged install flow for Isolated Web Apps. ',
            'Use `web_app::IsIwaUnmanagedInstallEnabled()` instead.',
        ),
        treat_as_error=True,
        excluded_paths=_TEST_CODE_EXCLUDED_PATHS + (
            '^chrome/browser/about_flags.cc',
            '^chrome/browser/web_applications/isolated_web_apps/isolated_web_app_features.cc',
        )),
    BanRule(
        pattern='/(CUIAutomation|AccessibleObjectFromWindow)',
        explanation=
        ('Direct usage of UIAutomation or IAccessible2 in client code is '
         'discouraged in Chromium, as it is not an assistive technology and '
         'should not rely on accessibility APIs directly. These APIs can '
         'introduce significant performance overhead. However, if you believe '
         'your use case warrants an exception, please discuss it with an '
         'accessibility owner before proceeding. For more information on the '
         'performance implications, see https://docs.google.com/document/d/1jN4itpCe_bDXF0BhFaYwv4xVLsCWkL9eULdzjmLzkuk/edit#heading=h.pwth3nbwdub0.',
         ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=r'/WIDGET_OWNS_NATIVE_WIDGET|'
        r'NATIVE_WIDGET_OWNS_WIDGET',
        explanation=
        ('WIDGET_OWNS_NATIVE_WIDGET and NATIVE_WIDGET_OWNS_WIDGET are in the '
         'process of being deprecated. Consider using the new '
         'CLIENT_OWNS_WIDGET ownership model. Eventually, this will be the only '
         'available ownership model available and the associated enumeration '
         'will be removed.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='ProfileManager::GetLastUsedProfile',
        explanation=
        ('Most code should already be scoped to a Profile. Pass in a Profile* '
         'or retrieve from an existing entity with a reference to the Profile '
         '(e.g. WebContents).', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=(r'/FindBrowserWithUiElementContext|'
                 r'FindBrowserWithTab|'
                 r'FindBrowserWithGroup|'
                 r'FindTabbedBrowser|'
                 r'FindAnyBrowser|'
                 r'FindBrowserWithProfile|'
                 r'FindLastActive|'
                 r'FindBrowserWithActiveWindow'),
        explanation=
        ('Most code should already be scoped to a Browser. Pass in a Browser* '
         'or retrieve from an existing entity with a reference to the Browser.',
         ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=r'subspan(0u,',
        explanation=(
            'Prefer first(n) over subspan(0u, n) as it is shorter, and the '
            'compiler may have to emit a branch for the n == dynamic_extent '
            'case of subspan().', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=r'UNSAFE_TODO(',
        explanation=(
            'Do not use UNSAFE_TODO() to write new unsafe code. Use only when '
            'removing a pre-existing file-wide allow_unsafe_buffers pragma, or '
            'when incrementally converting code off of unsafe interfaces', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='#pragma allow_unsafe_buffers',
        explanation=
        ('Do not use allow_unsafe_buffers to write new unsafe code. Use only '
         'when enabling unsafe buffers checks under a new uncovered path.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=r'UNSAFE_BUFFERS(',
        explanation=
        ('Try to avoid using UNSAFE_BUFFERS() if at all possible. Otherwise, '
         'be sure to justify in a // SAFETY comment why other options are not '
         'available, and why the code is safe.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='BrowserWithTestWindowTest',
        explanation=
        ('Do not use BrowserWithTestWindowTest. By instantiating an instance '
         'of class Browser, the test is no longer a unit test but is instead a '
         'browser test. The class BrowserWithTestWindowTest forces production '
         'logic to take on test-only conditionals, which is an anti-pattern. '
         'Features should be performing dependency injection rather than '
         'directly using class Browser. See '
         'docs/chrome_browser_design_principles.md for more details.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='TestWithBrowserView',
        explanation=
        ('Do not use TestWithBrowserView. See '
         'docs/chrome_browser_design_principles.md for details. If you want '
         'to write a test that has both a Browser and a BrowserView, create '
         'a browser_test. If you want to write a unit_test, your code must '
         'not reference Browser*.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='CreateBrowserWithTestWindow',
        explanation=
        ('Do not use CreateBrowserWithTestWindow. See '
         'docs/chrome_browser_design_principles.md for details. If you want '
         'to write a test that has a Browser, create a browser_test. If you '
         'want to write a unit_test, your code must not reference Browser*.',
         ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='CreateBrowserWithTestWindowForParams',
        explanation=
        ('Do not use CreateBrowserWithTestWindowForParams. See '
         'docs/chrome_browser_design_principles.md for details. If you want '
         'to write a test that has a Browser, create a browser_test and use '
         'Browser::Browser. If you want to write a unit_test, your code must '
         'not reference Browser*.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='TestBrowserWindow',
        explanation=
        ('Do not use TestBrowserWindow. See '
         'docs/chrome_browser_design_principles.md for details. If you want '
         'to write a test that has a Browser, create a browser_test. If you '
         'want to write a unit_test, your code should not reference Browser '
         'or BrowserWindow.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='RunUntilIdle',
        explanation=
        ('Do not RunUntilIdle. If possible, explicitly quit the run loop using '
         'run_loop.Quit() or run_loop.QuitClosure() if completion can be '
         'observed using a lambda or callback. Otherwise, wait for the '
         'condition to be true via base::test::RunUntil().', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=r'/\bstd::(literals|string_literals|string_view_literals)\b',
        explanation=(
            'User-defined literals are banned by the Google C++ style guide. '
            'Exceptions are provided in Chrome for string and string_view '
            'literals that embed \\0.', ),
        treat_as_error=True,
        excluded_paths=(
            # Various tests or test helpers that embed NUL in strings or
            # string_views.
            r'^base/strings/string_util_unittest\.cc',
            r'^base/strings/utf_string_conversions_unittest\.cc',
            r'^chromeos/ash/experiences/arc/session/serial_number_util_unittest\.cc',
            r'^components/history/core/browser/visit_annotations_database\.cc',
            r'^components/history/core/browser/visit_annotations_database_unittest\.cc',
            r'^components/os_crypt/sync/os_crypt_unittest\.cc',
            r'^components/password_manager/core/browser/credentials_cleaner_unittest\.cc',
            r'^content/browser/file_system_access/file_system_access_file_writer_impl_unittest\.cc',
            r'^net/cookies/parsed_cookie_unittest\.cc',
            r'^third_party/blink/renderer/modules/webcodecs/test_helpers\.cc',
            r'^third_party/blink/renderer/modules/websockets/websocket_channel_impl_test\.cc',
        ),
    ),
    BanRule(
        pattern='BUILDFLAG(GOOGLE_CHROME_BRANDING)',
        explanation=
        ('Code gated by GOOGLE_CHROME_BRANDING is effectively untested. This '
         'is typically wrong. Valid use cases are glue for private modules '
         'shipped alongside Chrome, and installation-related logic.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='defined(OFFICIAL_BUILD)',
        explanation=
        ('Code gated by OFFICIAL_BUILD is effectively untested. This '
         'is typically wrong. One valid use case is low-level code that '
         'handles subtleties related to high-levels of optimizations that come '
         'with OFFICIAL_BUILD.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='WebContentsDestroyed',
        explanation=
        ('Do not use this method. It is invoked half-way through the '
         'destructor of WebContentsImpl and using it often results in crashes '
         'or surprising behavior. Conceptually, this is only necessary by '
         'objects that depend on, but outlive the WebContents. These objects '
         'should instead coordinate with the owner of the WebContents which is '
         'responsible for destroying the WebContents.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern='IS_CHROMEOS_ASH',
        explanation=
        ('IS_CHROMEOS_ASH is deprecated. Please use the equivalent IS_CHROMEOS '
         'instead (Lacros is gone).', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=(r'namespace {'),
        explanation=
        ('Anonymous namespaces are disallowed in C++ header files. See '
         'https://google.github.io/styleguide/cppguide.html#Internal_Linkage '
         ' for details.', ),
        treat_as_error=False,
        excluded_paths=[
            _THIRD_PARTY_EXCEPT_BLINK,  # Don't warn in third_party folders.
            r'^(?!.*\.h$).*$',  # Exclude all files except those that end in .h
        ],
    ),
    BanRule(
        pattern=('AddChildViewRaw'),
        explanation=(
            'Do not use AddChildViewRaw. It is prone to memory leaks and '
            'use-after-free bugs. Instead, use AddChildView(std::unique_ptr). '
            'See https://crbug.com/40485510 for more details.', ),
        treat_as_error=False,
    ),
    BanRule(
        pattern=(r'IS_DESKTOP_ANDROID'),
        explanation=
        ('Usage of IS_DESKTOP_ANDROID build flag '
         'is discouraged. Use system affordances to determine feature '
         'availablility. Refer to https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ui/android/device_form_factor.md for guidelines. '
         'To request an exception, file a bug at '
         'https://b.corp.google.com/issues/new?component=1753515&template=2172655'
         'Once approved, use centralized util DeviceInfo.isDesktop() '
         'instead of direct build flag or PackageManager.FEATURE_PC checks. '
         'Allowances may be granted to only the directories below: '
         '[build/, chrome/, components/, extensions/, infra/, tools/] '
         'Note: in particular we need to avoid components shared with '
         'WebView.', ),
        treat_as_error=False,
        surface_as_gerrit_lint=True,
    ),
    BanRule(
        pattern='PageActionIconView',
        explanation=
        ('PageActionIconView will soon be removed. Use PageActionView instead. '
         'See chrome/browser/ui/views/page_action/README.md for details.'),
        treat_as_error=False,
    ),
    BanRule(
        pattern=(r'/\bkIgnoreCertificateErrors\b'),
        explanation=
        ('Usage of --ignore-certificate-errors in tests using '
         'net::EmbeddedTestServer to serve HTTPS requests is likely '
         'incorrect. Instead of blanket ignoring certificate errors using this '
         'switch, strongly prefer to configure the EmbeddedTestServer with a '
         'valid certificate for the relevant hostname(s). For tips on how to do '
         'so, see comment above the kIgnoreCertificateErrors switch definition '
         'or see https://www.chromium.org/developers/testing/browser-tests/#networking.',
         ),
        treat_as_error=True,
        excluded_paths=[
            _THIRD_PARTY_EXCEPT_BLINK,
            r'^(?!.*test\.cc$).*$',  # Only apply the ban in C++ test files.

            # Allowlisted tests that use kIgnoreCertificateErrors correctly, to
            # test behavior where the user has explicitly ignored cert errors.
            r'^chrome/browser/chrome_content_browser_client_unittest\.cc',
            r'^chrome/browser/extensions/api/web_request/web_request_apitest\.cc',
            r'^chrome/browser/ssl/ssl_browsertest\.cc',
            r'^components/network_session_configurator/browser/network_session_configurator_unittest\.cc',
            r'^content/browser/fenced_frame/fenced_frame_browsertest\.cc',
        ],
    ),
)

_DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING = (
    'Used a predicate related to signin::ConsentLevel::kSync which will always '
    'return false in the future (crbug.com/40066949). Prefer using a predicate '
    'that also supports signin::ConsentLevel::kSignin when appropriate. It is '
    'safe to ignore this warning if you are just moving an existing call, or if '
    'you want special handling for users in the legacy state. In doubt, reach '
    'out to //components/sync/OWNERS.', )

# C++ functions related to signin::ConsentLevel::kSync which are deprecated.
_DEPRECATED_SYNC_CONSENT_CPP_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        'HasSyncConsent',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'CanSyncFeatureStart',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'IsSyncFeatureEnabled',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'IsSyncFeatureActive',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
)

# Java functions related to signin::ConsentLevel::kSync which are deprecated.
_DEPRECATED_SYNC_CONSENT_JAVA_FUNCTIONS: Sequence[BanRule] = (
    BanRule(
        'hasSyncConsent',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'canSyncFeatureStart',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'isSyncFeatureEnabled',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
    BanRule(
        'isSyncFeatureActive',
        _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING,
        False,
    ),
)

_BANNED_MOJOM_PATTERNS: Sequence[BanRule] = (
    BanRule(
        'handle<shared_buffer>',
        (
            'Please use one of the more specific shared memory types instead:',
            '  mojo_base.mojom.ReadOnlySharedMemoryRegion',
            '  mojo_base.mojom.WritableSharedMemoryRegion',
            '  mojo_base.mojom.UnsafeSharedMemoryRegion',
        ),
        True,
    ),
    BanRule(
        'string extension_id',
        (
            'Please use the extensions::mojom::ExtensionId struct when '
            'passing extensions::ExtensionIds as mojom messages in order to ',
            'provide message validation.',
        ),
        True,
        # Only apply this to (mojom) files in a subdirectory of extensions.
        excluded_paths=(r'^((?!extensions/).)*$', ),
    ),
)

_IPC_ENUM_TRAITS_DEPRECATED = (
    'You are using IPC_ENUM_TRAITS() in your code. It has been deprecated.\n'
    'See http://www.chromium.org/Home/chromium-security/education/'
    'security-tips-for-ipc')

_LONG_PATH_ERROR = (
    'Some files included in this CL have file names that are too long (> 200'
    ' characters). If committed, these files will cause issues on Windows. See'
    ' https://crbug.com/612667 for more details.')

_JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS = [
    r'.*/BuildHooksAndroidImpl\.java',
    r'.*/LicenseContentProvider\.java',
    r'.*/PlatformServiceBridgeImpl.java',
    r'.*chrome/android/feed/dummy/.*\.java',
]

# List of image extensions that are used as resources in chromium.
_IMAGE_EXTENSIONS = ['.svg', '.png', '.webp']

# These paths contain test data and other known invalid JSON files.
_KNOWN_TEST_DATA_AND_INVALID_JSON_FILE_PATTERNS = [
    r'test/data/',
    r'testing/buildbot/',
    r'^components/policy/resources/policy_templates\.json$',
    r'^third_party/protobuf/',
    r'^third_party/blink/perf_tests/speedometer.*/resources/todomvc/learn\.json',
    r'^third_party/blink/renderer/devtools/protocol\.json$',
    r'^third_party/blink/web_tests/external/wpt/',
    r'^tools/perf/',
    r'^tools/traceline/svgui/startup-release.json',
    # vscode configuration files allow comments
    r'^tools/vscode/',
]

# These are not checked on the public linux-presubmit trybot.
# Add files here that rely on .py files that exists only for target_os="android"
# checkouts.
_ANDROID_SPECIFIC_PYDEPS_FILES = [
    'chrome/android/features/create_stripped_java_factory.pydeps',
]

_GENERIC_PYDEPS_FILES = [
    'android_webview/tools/run_cts.pydeps',
    'build/android/apk_operations.pydeps',
    'build/android/devil_chromium.pydeps',
    'build/android/gyp/aar.pydeps',
    'build/android/gyp/aidl.pydeps',
    'build/android/gyp/apkbuilder.pydeps',
    'build/android/gyp/assert_static_initializers.pydeps',
    'build/android/gyp/binary_baseline_profile.pydeps',
    'build/android/gyp/bytecode_rewriter.pydeps',
    'build/android/gyp/check_flag_expectations.pydeps',
    'build/android/gyp/check_for_missing_direct_deps.pydeps',
    'build/android/gyp/compile_java.pydeps',
    'build/android/gyp/compile_kt.pydeps',
    'build/android/gyp/compile_resources.pydeps',
    'build/android/gyp/copy_ex.pydeps',
    'build/android/gyp/create_apk_operations_script.pydeps',
    'build/android/gyp/create_app_bundle.pydeps',
    'build/android/gyp/create_app_bundle_apks.pydeps',
    'build/android/gyp/create_bundle_wrapper_script.pydeps',
    'build/android/gyp/create_java_binary_script.pydeps',
    'build/android/gyp/create_r_java.pydeps',
    'build/android/gyp/create_r_txt.pydeps',
    'build/android/gyp/create_size_info_files.pydeps',
    'build/android/gyp/create_stub_manifest.pydeps',
    'build/android/gyp/create_test_apk_wrapper_script.pydeps',
    'build/android/gyp/create_ui_locale_resources.pydeps',
    'build/android/gyp/dex.pydeps',
    'build/android/gyp/dist_aar.pydeps',
    'build/android/gyp/errorprone.pydeps',
    'build/android/gyp/filter_zip.pydeps',
    'build/android/gyp/flatc_java.pydeps',
    'build/android/gyp/gcc_preprocess.pydeps',
    'build/android/gyp/generate_linker_version_script.pydeps',
    'build/android/gyp/ijar.pydeps',
    'build/android/gyp/jacoco_instr.pydeps',
    'build/android/gyp/java_cpp_enum.pydeps',
    'build/android/gyp/java_cpp_features.pydeps',
    'build/android/gyp/java_cpp_strings.pydeps',
    'build/android/gyp/java_google_api_keys.pydeps',
    'build/android/gyp/jinja_template.pydeps',
    'build/android/gyp/lint.pydeps',
    'build/android/gyp/merge_manifest.pydeps',
    'build/android/gyp/optimize_resources.pydeps',
    'build/android/gyp/prepare_resources.pydeps',
    'build/android/gyp/process_native_prebuilt.pydeps',
    'build/android/gyp/proguard.pydeps',
    'build/android/gyp/rename_java_classes.pydeps',
    'build/android/gyp/system_image_apks.pydeps',
    'build/android/gyp/trace_event_bytecode_rewriter.pydeps',
    'build/android/gyp/tracereferences.pydeps',
    'build/android/gyp/turbine.pydeps',
    'build/android/gyp/unused_resources.pydeps',
    'build/android/gyp/validate_static_library_dex_references.pydeps',
    'build/android/gyp/write_build_config.pydeps',
    'build/android/gyp/write_native_libraries_java.pydeps',
    'build/android/gyp/zip.pydeps',
    'build/android/incremental_install/generate_android_manifest.pydeps',
    'build/android/incremental_install/write_installer_json.pydeps',
    'build/android/pylib/results/presentation/test_results_presentation.pydeps',
    'build/android/resource_sizes.pydeps',
    'build/android/test_runner.pydeps',
    'build/android/test_wrapper/logdog_wrapper.pydeps',
    'build/fuchsia/test/component_storage_test.pydeps',
    'build/protoc_java.pydeps',
    'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps',
    'chrome/test/chromedriver/test/run_py_tests.pydeps',
    'chrome/test/media/performance/openscreen_cast_performance_test.pydeps',
    'chrome/test/media/performance/videostack_performance_test.pydeps',
    'chromecast/resource_sizes/chromecast_resource_sizes.pydeps',
    'components/cronet/tools/check_combined_proguard_file.pydeps',
    'components/cronet/tools/generate_proguard_file.pydeps',
    'components/cronet/tools/jar_src.pydeps',
    'components/module_installer/android/module_desc_java.pydeps',
    'content/public/android/generate_child_service.pydeps',
    'fuchsia_web/av_testing/av_sync_tests.pydeps',
    'testing/scripts/run_isolated_script_test.pydeps',
    'testing/merge_scripts/standard_isolated_script_merge.pydeps',
    'testing/merge_scripts/standard_gtest_merge.pydeps',
    'testing/merge_scripts/code_coverage/merge_results.pydeps',
    'testing/merge_scripts/code_coverage/merge_steps.pydeps',
    'third_party/android_platform/development/scripts/stack.pydeps',
    'third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps',
    'third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps',
    'third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps',
    'third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps',
    'third_party/blink/renderer/bindings/scripts/generate_event_interface_names.pydeps',
    'third_party/blink/renderer/bindings/scripts/validate_web_idl.pydeps',
    'third_party/blink/tools/blinkpy/web_tests/merge_results.pydeps',
    'third_party/blink/tools/merge_web_test_results.pydeps',
    'tools/binary_size/sizes.pydeps',
    'tools/binary_size/supersize.pydeps',
    'tools/cygprofile/generate_orderfile.pydeps',
    'tools/perf/process_perf_results.pydeps',
    'tools/pgo/generate_profile.pydeps',
]

_ALL_PYDEPS_FILES = _ANDROID_SPECIFIC_PYDEPS_FILES + _GENERIC_PYDEPS_FILES

# Bypass the AUTHORS check for these accounts.
_KNOWN_ROBOTS = set() | set('%s@appspot.gserviceaccount.com' % s for s in (
    'findit-for-me', 'luci-bisection', 'predator-for-me-staging',
    'predator-for-me')) | set(
        '%s@developer.gserviceaccount.com' % s
        for s in ('3su6n15k.default', )) | set(
            '%s@chops-service-accounts.iam.gserviceaccount.com' % s
            for s in ('bling-autoroll-builder', 'v8-ci-autoroll-builder',
                      'wpt-autoroller', 'skylab-test-cros-roller',
                      'infra-try-recipes-tester',
                      'chrome-automated-expectation',
                      'chromium-automated-expectation', 'chrome-branch-day',
                      'chrome-cherry-picker', 'chromium-autosharder')
        ) | set(
            '%s@skia-public.iam.gserviceaccount.com' % s
            for s in ('chromium-autoroll', 'chromium-release-autoroll')) | set(
                '%s@skia-infra-corp.iam.gserviceaccount.com' % s
                for s in ('pinpoint-worker', )
            ) | set(
                '%s@skia-corp.google.com.iam.gserviceaccount.com' % s for s in
                ('chromium-internal-autoroll', )
            ) | set(
                '%s@system.gserviceaccount.com' % s for s in
                ('chrome-screen-ai-releaser', 'crash-eng', 'crash',
                 'meet-tools-roll-into-chromium')
            ) | set(
                '%s@owners-cleanup-prod.google.com.iam.gserviceaccount.com' % s
                for s in ('swarming-tasks', )) | set(
                    '%s@fuchsia-infra.iam.gserviceaccount.com' % s
                    for s in ('global-integration-try-builder',
                              'global-integration-ci-builder')
                ) | set('%s@prod.google.com' % s for s in (
                    'chops-security-borg',
                    'chops-security-cronjobs-cpesuggest')) | set(
                        '%s@chromeos-release-bot.iam.gserviceaccount.com' % s
                        for s in ('chromeos-ci-release', )) | set(
                            '%s@chromeos-bot.iam.gserviceaccount.com' % s
                            for s in ('chromeos-ci-prod', ))

_INVALID_GRD_FILE_LINE = [(r'<file lang=.* path=.*',
                           'Path should come before lang in GRD files.')]


def _IsCPlusPlusFile(input_api, file_path):
    """Returns True if this file contains C++-like code (and not Python,
    Go, Java, MarkDown, ...)"""

    ext = input_api.os_path.splitext(file_path)[1]
    # This list is compatible with CppChecker.IsCppFile but we should
    # consider adding ".c" to it. If we do that we can use this function
    # at more places in the code.
    return ext in (
        '.h',
        '.cc',
        '.cpp',
        '.m',
        '.mm',
    )


def _IsCPlusPlusHeaderFile(input_api, file_path):
    return input_api.os_path.splitext(file_path)[1] == '.h'


def _IsJavaFile(input_api, file_path):
    return input_api.os_path.splitext(file_path)[1] == '.java'


def _IsProtoFile(input_api, file_path):
    return input_api.os_path.splitext(file_path)[1] == '.proto'


def _IsXmlOrGrdFile(input_api, file_path):
    ext = input_api.os_path.splitext(file_path)[1]
    return ext in ('.grd', '.xml')


def _IsMojomFile(input_api, file_path):
    return input_api.os_path.splitext(file_path)[1] == '.mojom'


def CheckNoUpstreamDepsOnClank(input_api, output_api):
    """Prevent additions of dependencies from the upstream repo on //clank."""
    # clank can depend on clank
    if input_api.change.RepositoryRoot().endswith('clank'):
        return []
    build_file_patterns = [
        r'(.+/)?BUILD\.gn',
        r'.+\.gni',
    ]
    excluded_files = [r'build[/\\]config[/\\]android[/\\]config\.gni']
    bad_pattern = input_api.re.compile(r'^[^#]*//clank')

    error_message = 'Disallowed import on //clank in an upstream build file:'

    def FilterFile(affected_file):
        return input_api.FilterSourceFile(affected_file,
                                          files_to_check=build_file_patterns,
                                          files_to_skip=excluded_files)

    problems = []
    for f in input_api.AffectedSourceFiles(FilterFile):
        local_path = f.LocalPath()
        for line_number, line in f.ChangedContents():
            if (bad_pattern.search(line)):
                problems.append('%s:%d\n    %s' %
                                (local_path, line_number, line.strip()))
    if problems:
        return [output_api.PresubmitPromptOrNotify(error_message, problems)]
    else:
        return []


def CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
    """Attempts to prevent use of functions intended only for testing in
    non-testing code. For now this is just a best-effort implementation
    that ignores header files and may have some false positives. A
    better implementation would probably need a proper C++ parser.
    """
    # We only scan .cc files and the like, as the declaration of
    # for-testing functions in header files are hard to distinguish from
    # calls to such functions without a proper C++ parser.
    file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS]

    base_function_pattern = r'[ :]test::[^\s]+|ForTest(s|ing)?|for_test(s|ing)?'
    inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' %
                                             base_function_pattern)
    comment_pattern = input_api.re.compile(r'//.*(%s)' % base_function_pattern)
    allowlist_pattern = input_api.re.compile(r'// IN-TEST$')
    exclusion_pattern = input_api.re.compile(
        r'(::[A-Za-z0-9_]+(%s)|(%s))[^;]+\{' %
        (base_function_pattern, base_function_pattern))
    # Avoid a false positive in this case, where the method name, the ::, and
    # the closing { are all on different lines due to line wrapping.
    # HelperClassForTesting::
    #   HelperClassForTesting(
    #       args)
    #     : member(0) {}
    method_defn_pattern = input_api.re.compile(r'[A-Za-z0-9_]+::$')

    def FilterFile(affected_file):
        files_to_skip = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
                         input_api.DEFAULT_FILES_TO_SKIP)
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=file_inclusion_pattern,
            files_to_skip=files_to_skip)

    problems = []
    for f in input_api.AffectedSourceFiles(FilterFile):
        local_path = f.LocalPath()
        in_method_defn = False
        for line_number, line in f.ChangedContents():
            if (inclusion_pattern.search(line)
                    and not comment_pattern.search(line)
                    and not exclusion_pattern.search(line)
                    and not allowlist_pattern.search(line)
                    and not in_method_defn):
                problems.append('%s:%d\n    %s' %
                                (local_path, line_number, line.strip()))
            in_method_defn = method_defn_pattern.search(line)

    if problems:
        return [
            output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)
        ]
    else:
        return []


def CheckNoProductionCodeUsingTestOnlyFunctionsJava(input_api, output_api):
    """This is a simplified version of
    CheckNoProductionCodeUsingTestOnlyFunctions for Java files.
    """
    javadoc_start_re = input_api.re.compile(r'^\s*/\*\*')
    javadoc_end_re = input_api.re.compile(r'^\s*\*/')
    name_pattern = r'ForTest(s|ing)?'
    # Describes an occurrence of "ForTest*" inside a // comment.
    comment_re = input_api.re.compile(r'//.*%s' % name_pattern)
    # Describes @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
    annotation_re = input_api.re.compile(r'@VisibleForTesting\(')
    # Catch calls.
    inclusion_re = input_api.re.compile(r'(%s)\s*\(' % name_pattern)
    # Ignore definitions. (Comments are ignored separately.)
    exclusion_re = input_api.re.compile(r'(%s)[^;]+\{' % name_pattern)
    allowlist_re = input_api.re.compile(r'// IN-TEST$')

    problems = []
    sources = lambda x: input_api.FilterSourceFile(
        x,
        files_to_skip=(
            ('(?i).*test', r'.*\/junit\/') + input_api.DEFAULT_FILES_TO_SKIP),
        files_to_check=[r'.*\.java$'])
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=sources):
        local_path = f.LocalPath()
        is_inside_javadoc = False
        for line_number, line in f.ChangedContents():
            if is_inside_javadoc and javadoc_end_re.search(line):
                is_inside_javadoc = False
            if not is_inside_javadoc and javadoc_start_re.search(line):
                is_inside_javadoc = True
            if is_inside_javadoc:
                continue
            if (inclusion_re.search(line) and not comment_re.search(line)
                    and not annotation_re.search(line)
                    and not allowlist_re.search(line)
                    and not exclusion_re.search(line)):
                problems.append('%s:%d\n    %s' %
                                (local_path, line_number, line.strip()))

    if problems:
        return [
            output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)
        ]
    else:
        return []


def CheckNoIOStreamInHeaders(input_api, output_api):
    """Checks to make sure no .h files include <iostream>."""
    files = []
    pattern = input_api.re.compile(r'^#include\s*<iostream>',
                                   input_api.re.MULTILINE)
    for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
        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 #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 CheckNoStrCatRedefines(input_api, output_api):
    """Checks no windows headers with StrCat redefined are included directly."""
    files = []
    files_to_check = (r'.+%s' % _HEADER_EXTENSIONS,
                      r'.+%s' % _IMPLEMENTATION_EXTENSIONS)
    files_to_skip = (input_api.DEFAULT_FILES_TO_SKIP +
                     _NON_BASE_DEPENDENT_PATHS)
    sources_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=files_to_check, files_to_skip=files_to_skip)

    pattern_deny = input_api.re.compile(
        r'^#include\s*[<"](shlwapi|atlbase|propvarutil|sphelper).h[">]',
        input_api.re.MULTILINE)
    pattern_allow = input_api.re.compile(
        r'^#include\s"base/win/windows_defines.inc"', input_api.re.MULTILINE)
    for f in input_api.AffectedSourceFiles(sources_filter):
        contents = input_api.ReadFile(f)
        if pattern_deny.search(
                contents) and not pattern_allow.search(contents):
            files.append(f.LocalPath())

    if files:
        return [
            output_api.PresubmitError(
                'Do not #include shlwapi.h, atlbase.h, propvarutil.h or sphelper.h '
                'directly since they pollute code with StrCat macro. Instead, '
                'include matching header from base/win. See http://crbug.com/856536',
                files)
        ]
    return []


def _CheckNoUNIT_TESTInSourceFiles(input_api, f):
    problems = []

    unit_test_macro = input_api.re.compile(
        r'^\s*#.*(?:ifn?def\s+UNIT_TEST|defined\s*\(?\s*UNIT_TEST\s*\)?)(?:$|\s+)'
    )
    for line_num, line in f.ChangedContents():
        if unit_test_macro.match(line):
            problems.append('    %s:%d' % (f.LocalPath(), line_num))

    return problems


def CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
    """Checks to make sure no source files use UNIT_TEST."""
    problems = []
    for f in input_api.AffectedFiles():
        if (not f.LocalPath().endswith(('.cc', '.mm'))):
            continue
        problems.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, f))

    if not problems:
        return []
    return [
        output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
                                          '\n'.join(problems))
    ]


def CheckNoDISABLETypoInTests(input_api, output_api):
    """Checks to prevent attempts to disable tests with DISABLE_ prefix.

    This test warns if somebody tries to disable a test with the DISABLE_ prefix
    instead of DISABLED_. To filter false positives, reports are only generated
    if a corresponding MAYBE_ line exists.
    """
    problems = []

    # The following two patterns are looked for in tandem - is a test labeled
    # as MAYBE_ followed by a DISABLE_ (instead of the correct DISABLED)
    maybe_pattern = input_api.re.compile(r'MAYBE_([a-zA-Z0-9_]+)')
    disable_pattern = input_api.re.compile(r'DISABLE_([a-zA-Z0-9_]+)')

    # This is for the case that a test is disabled on all platforms.
    full_disable_pattern = input_api.re.compile(
        r'^\s*TEST[^(]*\([a-zA-Z0-9_]+,\s*DISABLE_[a-zA-Z0-9_]+\)',
        input_api.re.MULTILINE)

    for f in input_api.AffectedFiles(include_deletes=False):
        if not 'test' in f.LocalPath() or not f.LocalPath().endswith('.cc'):
            continue

        # Search for MAYBE_, DISABLE_ pairs.
        disable_lines = {}  # Maps of test name to line number.
        maybe_lines = {}
        for line_num, line in f.ChangedContents():
            disable_match = disable_pattern.search(line)
            if disable_match:
                disable_lines[disable_match.group(1)] = line_num
            maybe_match = maybe_pattern.search(line)
            if maybe_match:
                maybe_lines[maybe_match.group(1)] = line_num

        # Search for DISABLE_ occurrences within a TEST() macro.
        disable_tests = set(disable_lines.keys())
        maybe_tests = set(maybe_lines.keys())
        for test in disable_tests.intersection(maybe_tests):
            problems.append('    %s:%d' % (f.LocalPath(), disable_lines[test]))

        contents = input_api.ReadFile(f)
        full_disable_match = full_disable_pattern.search(contents)
        if full_disable_match:
            problems.append('    %s' % f.LocalPath())

    if not problems:
        return []
    return [
        output_api.PresubmitPromptWarning(
            'Attempt to disable a test with DISABLE_ instead of DISABLED_?\n' +
            '\n'.join(problems))
    ]


def CheckForgettingMAYBEInTests(input_api, output_api):
    """Checks to make sure tests disabled conditionally are not missing a
    corresponding MAYBE_ prefix.
    """
    # Expect at least a lowercase character in the test name. This helps rule out
    # false positives with macros wrapping the actual tests name.
    define_maybe_pattern = input_api.re.compile(
        r'^\#define MAYBE_(?P<test_name>\w*[a-z]\w*)')
    # The test_maybe_pattern needs to handle all of these forms. The standard:
    #   IN_PROC_TEST_F(SyncTest, MAYBE_Start) {
    # With a wrapper macro around the test name:
    #   IN_PROC_TEST_F(SyncTest, E2E_ENABLED(MAYBE_Start)) {
    # The optional E2E_ENABLED-style is handled with (\w*\()?
    test_maybe_pattern = (
        r'^\s*\w*TEST[^(]*\(\s*\w+,\s*(\w*\()?MAYBE_{test_name}')
    suite_maybe_pattern = r'^\s*\w*TEST[^(]*\(\s*MAYBE_{test_name}'
    warnings = []

    # Read the entire files. We can't just read the affected lines, forgetting to
    # add MAYBE_ on a change would not show up otherwise.
    for f in input_api.AffectedFiles(include_deletes=False):
        if not 'test' in f.LocalPath() or not f.LocalPath().endswith('.cc'):
            continue
        contents = input_api.ReadFile(f)
        lines = contents.splitlines(True)
        current_position = 0
        warning_test_names = set()
        for line_num, line in enumerate(lines, start=1):
            current_position += len(line)
            maybe_match = define_maybe_pattern.search(line)
            if maybe_match:
                test_name = maybe_match.group('test_name')
                # Do not warn twice for the same test.
                if (test_name in warning_test_names):
                    continue
                warning_test_names.add(test_name)

                # Attempt to find the corresponding MAYBE_ test or suite, starting from
                # the current position.
                test_match = input_api.re.compile(
                    test_maybe_pattern.format(test_name=test_name),
                    input_api.re.MULTILINE).search(contents, current_position)
                suite_match = input_api.re.compile(
                    suite_maybe_pattern.format(test_name=test_name),
                    input_api.re.MULTILINE).search(contents, current_position)
                if not test_match and not suite_match:
                    warnings.append(
                        output_api.PresubmitPromptWarning(
                            '%s:%d found MAYBE_ defined without corresponding test %s'
                            % (f.LocalPath(), line_num, test_name)))
    return warnings


def CheckDCHECK_IS_ONHasBraces(input_api, output_api):
    """Checks to make sure DCHECK_IS_ON() does not skip the parentheses."""
    errors = []
    pattern = input_api.re.compile(r'\bDCHECK_IS_ON\b(?!\(\))',
                                   input_api.re.MULTILINE)
    for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
        if (not f.LocalPath().endswith(('.cc', '.mm', '.h'))):
            continue
        for lnum, line in f.ChangedContents():
            if input_api.re.search(pattern, line):
                errors.append(
                    output_api.PresubmitError((
                        '%s:%d: Use of DCHECK_IS_ON() must be written as "#if '
                        + 'DCHECK_IS_ON()", not forgetting the parentheses.') %
                                              (f.LocalPath(), lnum)))
    return errors


# TODO(crbug/1138055): Reimplement CheckUmaHistogramChangesOnUpload check in a
# more reliable way. See
# https://chromium-review.googlesource.com/c/chromium/src/+/2500269


def CheckFlakyTestUsage(input_api, output_api):
    """Check that FlakyTest annotation is our own instead of the android one"""
    pattern = input_api.re.compile(r'import android.test.FlakyTest;')
    files = []
    for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
        if f.LocalPath().endswith('Test.java'):
            if pattern.search(input_api.ReadFile(f)):
                files.append(f)
    if files:
        return [
            output_api.PresubmitError(
                'Use org.chromium.base.test.util.FlakyTest instead of '
                'android.test.FlakyTest', files)
        ]
    return []


def CheckNoDEPSGIT(input_api, output_api):
    """Make sure .DEPS.git is never modified manually."""
    if any(f.LocalPath().endswith('.DEPS.git')
           for f in input_api.AffectedFiles()):
        return [
            output_api.PresubmitError(
                'Never commit changes to .DEPS.git. This file is maintained by an\n'
                'automated system based on what\'s in DEPS and your changes will be\n'
                'overwritten.\n'
                'See https://sites.google.com/a/chromium.org/dev/developers/how-tos/'
                'get-the-code#Rolling_DEPS\n'
                'for more information')
        ]
    return []


def CheckCrosApiNeedBrowserTest(input_api, output_api):
    """Check new crosapi should add browser test."""
    has_new_crosapi = False
    has_browser_test = False
    for f in input_api.AffectedFiles():
        path = f.UnixLocalPath()
        if (path.startswith('chromeos/crosapi/mojom')
                and _IsMojomFile(input_api, path) and f.Action() == 'A'):
            has_new_crosapi = True
        if path.endswith('browsertest.cc') or path.endswith('browser_test.cc'):
            has_browser_test = True
    if has_new_crosapi and not has_browser_test:
        return [
            output_api.PresubmitPromptWarning(
                'You are adding a new crosapi, but there is no file ends with '
                'browsertest.cc file being added or modified. It is important '
                'to add crosapi browser test coverage to avoid version '
                ' skew issues.\n'
                'Check //docs/lacros/test_instructions.md for more information.'
            )
        ]
    return []


def _GetMessageForMatchingType(input_api, affected_file, line_number, line,
                               ban_rule):
    """Helper method for checking for banned constructs.

    Returns an string composed of the name of the file, the line number where the
    match has been found and the additional text passed as |message| in case the
    target type name matches the text inside the line passed as parameter.
    """
    result = []

    # Ignore comments about banned types.
    if input_api.re.search(r'^ *//', line):
        return result
    # A // nocheck comment will bypass this error.
    if line.endswith(' nocheck'):
        return result

    matched = False
    if ban_rule.pattern[0:1] == '/':
        regex = ban_rule.pattern[1:]
        if input_api.re.search(regex, line):
            matched = True
    elif ban_rule.pattern in line:
        matched = True

    if matched:
        result.append('    %s:%d:' % (affected_file.LocalPath(), line_number))
        for line in ban_rule.explanation:
            result.append('      %s' % line)

    return result


def CheckNoBannedPatterns(input_api, output_api):
    """Make sure that banned patterns are not used."""
    results = []

    def IsExcludedFile(affected_file, excluded_paths):
        if not excluded_paths:
            return False

        local_path = affected_file.UnixLocalPath()
        for item in excluded_paths:
            if input_api.re.match(item, local_path):
                return True
        return False

    def IsIosObjcFile(affected_file):
        local_path = affected_file.LocalPath()
        if input_api.os_path.splitext(local_path)[-1] not in ('.mm', '.m',
                                                              '.h'):
            return False
        basename = input_api.os_path.basename(local_path)
        if 'ios' in basename.split('_'):
            return True
        for sep in (input_api.os_path.sep, input_api.os_path.altsep):
            if sep and 'ios' in local_path.split(sep):
                return True
        return False

    def CheckForMatch(affected_file, line_num: int, line: str,
                      ban_rule: BanRule):
        if IsExcludedFile(affected_file, ban_rule.excluded_paths):
            return

        message = _GetMessageForMatchingType(input_api, f, line_num, line,
                                             ban_rule)
        if message:
            result_loc = []
            if ban_rule.surface_as_gerrit_lint:
                result_loc.append(
                    output_api.PresubmitResultLocation(
                        file_path=affected_file.LocalPath(),
                        start_line=line_num,
                        end_line=line_num,
                    ))
            if ban_rule.treat_as_error:
                results.append(
                    output_api.PresubmitError('A banned pattern was used.\n' +
                                              '\n'.join(message),
                                              locations=result_loc))

            else:
                results.append(
                    output_api.PresubmitPromptWarning(
                        'A banned pattern was used.\n' + '\n'.join(message),
                        locations=result_loc))

    file_filter = lambda f: f.LocalPath().endswith(('.java'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_JAVA_FUNCTIONS + _BANNED_JAVA_IMPORTS:
                CheckForMatch(f, line_num, line, ban_rule)

    file_filter = lambda f: f.LocalPath().endswith(('.js', '.ts'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_JAVASCRIPT_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_OBJC_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    for f in input_api.AffectedFiles(file_filter=IsIosObjcFile):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_IOS_OBJC_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    egtest_filter = lambda f: f.LocalPath().endswith(('_egtest.mm'))
    for f in input_api.AffectedFiles(file_filter=egtest_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_IOS_EGTEST_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_CPP_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    # As of 05/2024, iOS fully migrated ConsentLevel::kSync to kSignin, and
    # Android is in the process of preventing new users from entering kSync.
    # So the warning is restricted to those platforms.
    ios_pattern = input_api.re.compile(r'(^|[\W_])ios[\W_]')
    file_filter = lambda f: (
        f.LocalPath().endswith(('.cc', '.mm', '.h')) and
        ('android' in f.LocalPath() or
         # Simply checking for an 'ios' substring would
         # catch unrelated cases, use a regex.
         ios_pattern.search(f.LocalPath())))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _DEPRECATED_SYNC_CONSENT_CPP_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    file_filter = lambda f: f.LocalPath().endswith(('.java'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _DEPRECATED_SYNC_CONSENT_JAVA_FUNCTIONS:
                CheckForMatch(f, line_num, line, ban_rule)

    file_filter = lambda f: f.LocalPath().endswith(('.mojom'))
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            for ban_rule in _BANNED_MOJOM_PATTERNS:
                CheckForMatch(f, line_num, line, ban_rule)

    return results


def CheckNoPragmaOnce(input_api, output_api):
    """Make sure #pragma once is not used."""
    files = []
    pattern = input_api.re.compile(r'^#pragma\s+once', input_api.re.MULTILINE)
    for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
        if not f.LocalPath().endswith('.h'):
            continue
        if f.LocalPath().endswith('com_imported_mstscax.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 CheckNoTrinaryTrueFalse(input_api, output_api):
    """Checks to make sure we don't introduce use of foo ? true : false."""
    problems = []
    pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
    for f in input_api.AffectedFiles():
        if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
            continue

        for line_num, line in f.ChangedContents():
            if pattern.match(line):
                problems.append('    %s:%d' % (f.LocalPath(), line_num))

    if not problems:
        return []
    return [
        output_api.PresubmitPromptWarning(
            'Please consider avoiding the "? true : false" pattern if possible.\n'
            + '\n'.join(problems))
    ]


def CheckUnwantedDependencies(input_api, output_api):
    """Runs checkdeps on #include and import statements added in this
    change. Breaking - rules is an error, breaking ! rules is a
    warning.
    """
    # Return early if no relevant file types were modified.
    for f in input_api.AffectedFiles():
        path = f.LocalPath()
        if (_IsCPlusPlusFile(input_api, path) or _IsProtoFile(input_api, path)
                or _IsJavaFile(input_api, path)):
            break
    else:
        return []

    import sys
    # 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__.
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'buildtools', 'checkdeps')
        ]
        import checkdeps
        from rules import Rule
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    added_includes = []
    added_imports = []
    added_java_imports = []
    for f in input_api.AffectedFiles():
        if _IsCPlusPlusFile(input_api, f.LocalPath()):
            changed_lines = [line for _, line in f.ChangedContents()]
            added_includes.append([f.AbsoluteLocalPath(), changed_lines])
        elif _IsProtoFile(input_api, f.LocalPath()):
            changed_lines = [line for _, line in f.ChangedContents()]
            added_imports.append([f.AbsoluteLocalPath(), changed_lines])
        elif _IsJavaFile(input_api, f.LocalPath()):
            changed_lines = [line for _, line in f.ChangedContents()]
            added_java_imports.append([f.AbsoluteLocalPath(), changed_lines])

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

    error_descriptions = []
    warning_descriptions = []
    error_subjects = set()
    warning_subjects = set()

    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
            added_includes):
        path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
            error_subjects.add('#includes')
        else:
            warning_descriptions.append(description_with_path)
            warning_subjects.add('#includes')

    for path, rule_type, rule_description in deps_checker.CheckAddedProtoImports(
            added_imports):
        path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
            error_subjects.add('imports')
        else:
            warning_descriptions.append(description_with_path)
            warning_subjects.add('imports')

    for path, rule_type, rule_description in deps_checker.CheckAddedJavaImports(
            added_java_imports, _JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS):
        path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
            error_subjects.add('imports')
        else:
            warning_descriptions.append(description_with_path)
            warning_subjects.add('imports')

    results = []
    if error_descriptions:
        results.append(
            output_api.PresubmitError(
                'You added one or more %s that violate checkdeps rules.' %
                ' and '.join(error_subjects), error_descriptions))
    if warning_descriptions:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You added one or more %s of files that are temporarily\n'
                'allowed but being removed. Can you avoid introducing the\n'
                '%s? See relevant DEPS file(s) for details and contacts.' %
                (' and '.join(warning_subjects), '/'.join(warning_subjects)),
                warning_descriptions))
    return results


def CheckFilePermissions(input_api, output_api):
    """Check that all files have their permissions properly set."""
    if input_api.platform == 'win32':
        return []
    checkperms_tool = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                             'tools', 'checkperms',
                                             'checkperms.py')
    args = [
        input_api.python3_executable, checkperms_tool, '--root',
        input_api.change.RepositoryRoot()
    ]
    with input_api.CreateTemporaryFile() as file_list:
        for f in input_api.AffectedFiles():
            # checkperms.py file/directory arguments must be relative to the
            # repository.
            file_list.write((f.LocalPath() + '\n').encode('utf8'))
        file_list.close()
        args += ['--file-list', file_list.name]
        try:
            input_api.subprocess.check_output(args)
            return []
        except input_api.subprocess.CalledProcessError as error:
            return [
                output_api.PresubmitError('checkperms.py failed:',
                                          long_text=error.output.decode(
                                              'utf-8', 'ignore'))
            ]


def CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
    """Makes sure we don't include ui/aura/window_property.h
    in header files.
    """
    pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
    errors = []
    for f in input_api.AffectedFiles():
        if not f.LocalPath().endswith('.h'):
            continue
        for line_num, line in f.ChangedContents():
            if pattern.match(line):
                errors.append('    %s:%d' % (f.LocalPath(), line_num))

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'Header files should not include ui/aura/window_property.h',
                errors))
    return results


def CheckNoInternalHeapIncludes(input_api, output_api):
    """Makes sure we don't include any headers from
    third_party/blink/renderer/platform/heap/impl or
    third_party/blink/renderer/platform/heap/v8_wrapper from files outside of
    third_party/blink/renderer/platform/heap
    """
    impl_pattern = input_api.re.compile(
        r'^\s*#include\s*"third_party/blink/renderer/platform/heap/impl/.*"')
    v8_wrapper_pattern = input_api.re.compile(
        r'^\s*#include\s*"third_party/blink/renderer/platform/heap/v8_wrapper/.*"'
    )
    file_filter = lambda f: not input_api.re.match(
        r'^third_party/blink/renderer/platform/heap/.*', f.UnixLocalPath())
    errors = []

    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            if impl_pattern.match(line) or v8_wrapper_pattern.match(line):
                errors.append('    %s:%d' % (f.LocalPath(), line_num))

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'Do not include files from third_party/blink/renderer/platform/heap/impl'
                ' or third_party/blink/renderer/platform/heap/v8_wrapper. Use the '
                'relevant counterparts from third_party/blink/renderer/platform/heap',
                errors))
    return results


def _CheckForVersionControlConflictsInFile(input_api, f):
    pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
    errors = []
    for line_num, line in f.ChangedContents():
        if f.LocalPath().endswith(('.md', '.rst', '.txt')):
            # First-level headers in markdown look a lot like version control
            # conflict markers. http://daringfireball.net/projects/markdown/basics
            continue
        if pattern.match(line):
            errors.append('    %s:%d %s' % (f.LocalPath(), line_num, line))
    return errors


def CheckForVersionControlConflicts(input_api, output_api):
    """Usually this is not intentional and will cause a compile failure."""
    errors = []
    for f in input_api.AffectedFiles():
        errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'Version control conflict markers found, please resolve.',
                errors))
    return results


def CheckGoogleSupportAnswerUrlOnUpload(input_api, output_api):
    pattern = input_api.re.compile(r'support\.google\.com\/chrome.*/answer')
    errors = []
    for f in input_api.AffectedFiles():
        for line_num, line in f.ChangedContents():
            if pattern.search(line):
                errors.append('    %s:%d %s' % (f.LocalPath(), line_num, line))

    results = []
    if errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Found Google support URL addressed by answer number. Please replace '
                'with a p= identifier instead. See crbug.com/679462\n',
                errors))
    return results


def CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):

    def FilterFile(affected_file):
        """Filter function for use with input_api.AffectedSourceFiles,
        below.  This filters out everything except non-test files from
        top-level directories that generally speaking should not hard-code
        service URLs (e.g. src/android_webview/, src/content/ and others).
        """
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=[r'^(android_webview|base|content|net)/.*'],
            files_to_skip=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
                           input_api.DEFAULT_FILES_TO_SKIP))

    base_pattern = (r'"[^"]*(google|googleapis|googlezip|googledrive|appspot)'
                    r'\.(com|net)[^"]*"')
    comment_pattern = input_api.re.compile('//.*%s' % base_pattern)
    pattern = input_api.re.compile(base_pattern)
    problems = []  # items are (filename, line_number, line)
    for f in input_api.AffectedSourceFiles(FilterFile):
        for line_num, line in f.ChangedContents():
            if not comment_pattern.search(line) and pattern.search(line):
                problems.append((f.LocalPath(), line_num, line))

    if problems:
        return [
            output_api.PresubmitPromptOrNotify(
                'Most layers below src/chrome/ should not hardcode service URLs.\n'
                'Are you sure this is correct?', [
                    '  %s:%d:  %s' % (problem[0], problem[1], problem[2])
                    for problem in problems
                ])
        ]
    else:
        return []


def CheckChromeOsSyncedPrefRegistration(input_api, output_api):
    """Warns if Chrome OS C++ files register syncable prefs as browser prefs."""

    def FileFilter(affected_file):
        """Includes directories known to be Chrome OS only."""
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=(
                '^ash/',
                '^chromeos/',  # Top-level src/chromeos.
                '.*/chromeos/',  # Any path component.
                '^components/arc',
                '^components/exo'),
            files_to_skip=(input_api.DEFAULT_FILES_TO_SKIP))

    prefs = []
    priority_prefs = []
    for f in input_api.AffectedFiles(file_filter=FileFilter):
        for line_num, line in f.ChangedContents():
            if input_api.re.search('PrefRegistrySyncable::SYNCABLE_PREF',
                                   line):
                prefs.append('    %s:%d:' % (f.LocalPath(), line_num))
                prefs.append('      %s' % line)
            if input_api.re.search(
                    'PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF', line):
                priority_prefs.append('    %s:%d' % (f.LocalPath(), line_num))
                priority_prefs.append('      %s' % line)

    results = []
    if (prefs):
        results.append(
            output_api.PresubmitPromptWarning(
                'Preferences were registered as SYNCABLE_PREF and will be controlled '
                'by browser sync settings. If these prefs should be controlled by OS '
                'sync settings use SYNCABLE_OS_PREF instead.\n' +
                '\n'.join(prefs)))
    if (priority_prefs):
        results.append(
            output_api.PresubmitPromptWarning(
                'Preferences were registered as SYNCABLE_PRIORITY_PREF and will be '
                'controlled by browser sync settings. If these prefs should be '
                'controlled by OS sync settings use SYNCABLE_OS_PRIORITY_PREF '
                'instead.\n' + '\n'.join(prefs)))
    return results


def CheckNoAbbreviationInPngFileName(input_api, output_api):
    """Makes sure there are no abbreviations in the name of PNG files.
    """
    errors = []
    files_to_check = [r'.*\.png$']
    files_to_skip = [
        r'^services/test/',
        r'^third_party/blink/web_tests/',
    ]
    file_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=files_to_check, files_to_skip=files_to_skip)
    abbreviation = input_api.re.compile(r'.+_[a-z]\.png|.+_[a-z]_.*\.png')
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        file_name = input_api.os_path.split(f.LocalPath())[1]
        if abbreviation.search(file_name):
            errors.append('    %s' % f.LocalPath())

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'The name of PNG files should not have abbreviations. \n'
                'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
                'Contact oshima@chromium.org if you have questions.', errors))
    return results


def CheckNoProductIconsAddedToPublicRepo(input_api, output_api):
    """Heuristically identifies product icons based on their file name and reminds
    contributors not to add them to the Chromium repository.
    """

    if input_api.change.RepositoryRoot().endswith('clank'):
        # TODO(crbug.com/414435241): Change check to compute whether change
        # belongs to internal repository instead of relying on string matching.
        return []

    errors = []
    files_to_check = [r'.*google.*\.png$|.*google.*\.svg$|.*google.*\.icon$']
    file_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=files_to_check)
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        errors.append('    %s' % f.LocalPath())

    results = []
    if errors:
        # Give warnings instead of errors on presubmit --all and presubmit
        # --files.
        message_type = (output_api.PresubmitNotifyResult
                        if input_api.no_diffs else output_api.PresubmitError)
        results.append(
            message_type(
                'Trademarked images should not be added to the public repo. '
                'See crbug.com/944754', errors))
    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:
                raise Exception('Var is not defined: %s' % var_name)

    local_scope = {}
    global_scope = {
        'Var': _VarImpl(local_scope).Lookup,
        'Str': str,
    }

    exec(contents, global_scope, local_scope)
    return local_scope


def _FindAllDepsFilesForSubpath(input_api, subpath):
    ret = []
    while subpath:
        cur = input_api.os_path.join(input_api.change.RepositoryRoot(),
                                     subpath, 'DEPS')
        if input_api.os_path.isfile(cur):
            ret.append(cur)
        subpath = input_api.os_path.dirname(subpath)
    return ret


def _FindAddedDepsThatRequireReview(input_api, depended_on_paths):
    """Filters to those whose DEPS set new_usages_require_review=True"""
    ret = set()
    cache = {}
    for target_path in depended_on_paths:
        for subpath in _FindAllDepsFilesForSubpath(input_api, target_path):
            config = cache.get(subpath)
            if config is None:
                config = _ParseDeps(input_api.ReadFile(subpath))
                cache[subpath] = config
            if config.get('new_usages_require_review'):
                ret.add(target_path)
                break
    return ret


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 CheckForNewDEPSDownloadFromGoogleStorageHooks(input_api, output_api):
    """Checks that there are no new download_from_google_storage hooks"""
    for f in input_api.AffectedFiles(include_deletes=False):
        if f.LocalPath() == 'DEPS':
            old_hooks = _ParseDeps('\n'.join(f.OldContents()))['hooks']
            new_hooks = _ParseDeps('\n'.join(f.NewContents()))['hooks']
            old_name_to_hook = {hook['name']: hook for hook in old_hooks}
            new_name_to_hook = {hook['name']: hook for hook in new_hooks}
            added_hook_names = set(new_name_to_hook.keys()) - set(
                old_name_to_hook.keys())
            if not added_hook_names:
                return []
            new_download_from_google_storage_hooks = []
            for new_hook in added_hook_names:
                hook = new_name_to_hook[new_hook]
                action_cmd = hook['action']
                if any('download_from_google_storage' in arg
                       for arg in action_cmd):
                    new_download_from_google_storage_hooks.append(new_hook)
            if new_download_from_google_storage_hooks:
                return [
                    output_api.PresubmitError(
                        'Please do not add new download_from_google_storage '
                        'hooks. Instead, add a `gcs` dep_type entry to `deps`. '
                        'See https://chromium.googlesource.com/chromium/src.git'
                        '/+/refs/heads/main/docs/gcs_dependencies.md for more '
                        'info. Added hooks:',
                        items=new_download_from_google_storage_hooks)
                ]
    return []


def CheckEachPerfettoTestDataFileHasDepsEntry(input_api, output_api):
    test_data_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=[r'^base/tracing/test/data_sha256/.*\.sha256'])
    if not any(input_api.AffectedFiles(file_filter=test_data_filter)):
        return []

    # Find DEPS entry
    deps_entry = []
    old_deps_entry = []
    for f in input_api.AffectedFiles(include_deletes=False):
        if f.LocalPath() == 'DEPS':
            new_deps = _ParseDeps('\n'.join(f.NewContents()))['deps']
            deps_entry = new_deps['src/base/tracing/test/data']
            old_deps = _ParseDeps('\n'.join(f.OldContents()))['deps']
            old_deps_entry = old_deps['src/base/tracing/test/data']
    if not deps_entry:
        # TODO(312895063):Add back error when .sha256 files have been moved.
        return [
            output_api.PresubmitError(
                'You must update the DEPS file when you update a '
                '.sha256 file in base/tracing/test/data_sha256')
        ]

    output = []
    for f in input_api.AffectedFiles(file_filter=test_data_filter):
        objects = deps_entry['objects']
        if not f.NewContents():
            # Deleted file so check that DEPS entry removed
            sha256_from_file = f.OldContents()[0]
            object_entry = next(
                (item
                 for item in objects if item['sha256sum'] == sha256_from_file),
                None)
            old_entry = next((item for item in old_deps_entry['objects']
                              if item['sha256sum'] == sha256_from_file), None)
            if object_entry:
                # Allow renaming of objects with the same hash
                if object_entry['object_name'] != old_entry['object_name']:
                    continue
                output.append(
                    output_api.PresubmitError(
                        'You deleted %s so you must also remove the corresponding DEPS entry.'
                        % f.LocalPath()))
            continue

        sha256_from_file = f.NewContents()[0]
        object_entry = next(
            (item
             for item in objects if item['sha256sum'] == sha256_from_file),
            None)
        if not object_entry:
            output.append(
                output_api.PresubmitError(
                    'No corresponding DEPS entry found for %s. '
                    'Run `base/tracing/test/test_data.py get_deps --filepath %s` '
                    'to generate the DEPS entry.' %
                    (f.LocalPath(), f.LocalPath())))

    if output:
        output.append(
            output_api.PresubmitError(
                'The DEPS entry for `src/base/tracing/test/data` in the DEPS file has not been '
                'updated properly. Run `base/tracing/test/test_data.py get_all_deps` to see what '
                'the DEPS entry should look like.'))
    return output


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.
    """
    # We rely on Gerrit's code-owners to check approvals.
    # input_api.gerrit is always set for Chromium, but other projects
    # might not use Gerrit.
    if not input_api.gerrit or input_api.no_diffs:
        return []
    if 'PRESUBMIT_SKIP_NETWORK' in input_api.environ:
        return []
    try:
        if (input_api.change.issue
                and input_api.gerrit.IsOwnersOverrideApproved(
                    input_api.change.issue)):
            # Skip OWNERS check when Owners-Override label is approved. This is
            # intended for global owners, trusted bots, and on-call sheriffs.
            # Review is still required for these changes.
            return []
    except Exception as e:
        return [
            output_api.PresubmitPromptWarning(
                'Failed to retrieve owner override status - %s' % str(e))
        ]

    # A set of paths (that might not exist) that are being added as DEPS
    # (via lines like "+foo/bar/baz").
    depended_on_paths = set()

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

    # Requiring reviews is opt-in as of https://crbug.com/365797506
    depended_on_paths = _FindAddedDepsThatRequireReview(
        input_api, depended_on_paths)
    if not depended_on_paths:
        return []

    if input_api.is_committing:
        if input_api.tbr:
            return [
                output_api.PresubmitNotifyResult(
                    '--tbr was specified, skipping OWNERS check for DEPS additions'
                )
            ]
        # TODO(dcheng): Make this generate an error on dry runs if the reviewer
        # is not added, to prevent review serialization.
        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(
        depended_on_paths, reviewers.union([owner_email]), [])
    missing_files = [
        p for p in depended_on_paths
        if approval_status[p] != 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]
        else:
            return path

    submodule_paths = set(input_api.ListSubmodules())

    def is_from_submodules(path, submodule_paths):
        path = input_api.os_path.normpath(path)
        while path:
            if path in submodule_paths:
                return True

            # All deps should be a relative path from the checkout.
            # i.e., shouldn't start with "/" or "c:\", for example.
            #
            # That said, this is to prevent an infinite loop, just in case
            # an input dep path starts with "/", because
            # os.path.dirname("/") => "/"
            parent = input_api.os_path.dirname(path)
            if parent == path:
                break
            path = parent

        return False

    unapproved_dependencies = [
        "'+%s'," % StripDeps(path) for path in missing_files
        # if a newly added dep is from a submodule, it becomes trickier
        # to get suggested owners, especially it is from a different host.
        #
        # skip the review enforcement for cross-repo deps.
        if not is_from_submodules(path, submodule_paths)
    ]

    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 []


# TODO: add unit tests.
def CheckSpamLogging(input_api, output_api):
    file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS]
    files_to_skip = (
        _EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
        input_api.DEFAULT_FILES_TO_SKIP + (
            r'^base/fuchsia/scoped_fx_logger\.cc$',
            r'^base/logging\.h$',
            r'^base/logging\.cc$',
            r'^base/task/thread_pool/task_tracker\.cc$',
            r'^chrome/app/chrome_main_delegate\.cc$',
            r'^chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer\.cc$',
            r'^chrome/browser/ash/policy/remote_commands/user_command_arc_job\.cc$',
            r'^chrome/browser/chrome_browser_main\.cc$',
            r'^chrome/browser/ui/startup/startup_browser_creator\.cc$',
            r'^chrome/browser/browser_switcher/bho/.*',
            r'^chrome/browser/diagnostics/diagnostics_writer\.cc$',
            r'^chrome/chrome_elf/dll_hash/dll_hash_main\.cc$',
            r'^chrome/installer/setup/.*',
            # crdmg runs as a separate binary which intentionally does
            # not depend on base logging.
            r'^chrome/utility/safe_browsing/mac/crdmg\.cc$',
            r'^chromecast/',
            r'^components/cast',
            r'^components/media_control/renderer/media_playback_options\.cc$',
            r'^components/policy/core/common/policy_logger\.cc$',
            r'^components/supervised_user/core/browser/android/content_filters_observer_bridge\.cc',
            r'^components/viz/service/display/'
            r'overlay_strategy_underlay_cast\.cc$',
            r'^components/zucchini/.*',
            # TODO(peter): Remove exception. https://crbug.com/534537
            r'^content/browser/notifications/notification_event_dispatcher_impl\.cc$',
            r'^content/common/gpu/client/gl_helper_benchmark\.cc$',
            r'^courgette/courgette_minimal_tool\.cc$',
            r'^courgette/courgette_tool\.cc$',
            r'^extensions/renderer/logging_native_handler\.cc$',
            r'^fuchsia_web/common/init_logging\.cc$',
            r'^fuchsia_web/runners/common/web_component\.cc$',
            r'^fuchsia_web/shell/.*\.cc$',
            r'^headless/app/headless_shell\.cc$',
            r'^ipc/ipc_logging\.cc$',
            r'^ios/chrome/app/perf_tests_hook_logging\.mm$',
            r'^remoting/base/logging\.h$',
            r'^remoting/host/.*',
            r'^sandbox/linux/.*',
            r'^services/webnn/tflite/graph_impl_tflite\.cc$',
            r'^services/webnn/coreml/graph_impl_coreml\.mm$',
            r'^storage/browser/file_system/dump_file_system\.cc$',
            r'^testing/perf/',
            r'^tools/',
            r'^ui/base/resource/data_pack\.cc$',
            r'^ui/aura/bench/bench_main\.cc$',
            r'^ui/ozone/platform/cast/',
            r'^ui/base/x/xwmstartupcheck/xwmstartupcheck\.cc$'))
    source_file_filter = lambda x: input_api.FilterSourceFile(
        x, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)

    log_info = set([])
    printf = set([])

    for f in input_api.AffectedSourceFiles(source_file_filter):
        for _, line in f.ChangedContents():
            if input_api.re.search(r'\bD?LOG\s*\(\s*INFO\s*\)', line):
                log_info.add(f.LocalPath())
            elif input_api.re.search(r'\bD?LOG_IF\s*\(\s*INFO\s*,', line):
                log_info.add(f.LocalPath())

            if input_api.re.search(r'\bprintf\(', line):
                printf.add(f.LocalPath())
            elif input_api.re.search(r'\bfprintf\((stdout|stderr)', line):
                printf.add(f.LocalPath())

    if log_info:
        return [
            output_api.PresubmitError(
                'These files spam the console log with LOG(INFO):',
                items=log_info)
        ]
    if printf:
        return [
            output_api.PresubmitError(
                'These files spam the console log with printf/fprintf:',
                items=printf)
        ]
    return []


def CheckUniquePtrOnUpload(input_api, output_api):
    # Returns whether |template_str| is of the form <T, U...> for some types T
    # and U, or is invalid due to mismatched angle bracket pairs. Assumes that
    # |template_str| is already in the form <...>.
    def HasMoreThanOneArgOrInvalid(template_str):
        # Level of <...> nesting.
        nesting = 0
        for c in template_str:
            if c == '<':
                nesting += 1
            elif c == '>':
                nesting -= 1
            elif c == ',' and nesting == 1:
                return True
        if nesting != 0:
            # Invalid.
            return True
        return False

    file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS]
    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + input_api.
                       DEFAULT_FILES_TO_SKIP),
        files_to_check=file_inclusion_pattern)

    # Pattern to capture a single "<...>" block of template arguments. It can
    # handle linearly nested blocks, such as "<std::vector<std::set<T>>>", but
    # cannot handle branching structures, such as "<pair<set<T>,set<U>>". The
    # latter would likely require counting that < and > match, which is not
    # expressible in regular languages. Should the need arise, one can introduce
    # limited counting (matching up to a total number of nesting depth), which
    # should cover all practical cases for already a low nesting limit.
    template_arg_pattern = (
        r'<[^>]*'  # Opening block of <.
        r'>([^<]*>)?')  # Closing block of >.
    # Prefix expressing that whatever follows is not already inside a <...>
    # block.
    not_inside_template_arg_pattern = r'(^|[^<,\s]\s*)'
    null_construct_pattern = input_api.re.compile(
        not_inside_template_arg_pattern + r'\bstd::unique_ptr' +
        template_arg_pattern + r'\(\)')

    # Same as template_arg_pattern, but excluding type arrays, e.g., <T[]>.
    template_arg_no_array_pattern = (
        r'<[^>]*[^]]'  # Opening block of <.
        r'>([^(<]*[^]]>)?')  # Closing block of >.
    # Prefix saying that what follows is the start of an expression.
    start_of_expr_pattern = r'(=|\breturn|^)\s*'
    # Suffix saying that what follows are call parentheses with a non-empty list
    # of arguments.
    nonempty_arg_list_pattern = r'\(([^)]|$)'
    # Put the template argument into a capture group for deeper examination later.
    return_construct_pattern = input_api.re.compile(
        start_of_expr_pattern + r'std::unique_ptr' + '(?P<template_arg>' +
        template_arg_no_array_pattern + ')' + nonempty_arg_list_pattern)

    problems_constructor = []
    problems_nullptr = []
    for f in input_api.AffectedSourceFiles(sources):
        for line_number, line in f.ChangedContents():
            # Disallow:
            # return std::unique_ptr<T>(foo);
            # bar = std::unique_ptr<T>(foo);
            # But allow:
            # return std::unique_ptr<T[]>(foo);
            # bar = std::unique_ptr<T[]>(foo);
            # And also allow cases when the second template argument is present. Those
            # cases cannot be handled by std::make_unique:
            # return std::unique_ptr<T, U>(foo);
            # bar = std::unique_ptr<T, U>(foo);
            local_path = f.LocalPath()
            return_construct_result = return_construct_pattern.search(line)
            if return_construct_result and not HasMoreThanOneArgOrInvalid(
                    return_construct_result.group('template_arg')):
                problems_constructor.append(
                    '%s:%d\n    %s' % (local_path, line_number, line.strip()))
            # Disallow:
            # std::unique_ptr<T>()
            if null_construct_pattern.search(line):
                problems_nullptr.append(
                    '%s:%d\n    %s' % (local_path, line_number, line.strip()))

    errors = []
    if problems_nullptr:
        errors.append(
            output_api.PresubmitPromptWarning(
                'The following files use std::unique_ptr<T>(). Use nullptr instead.',
                problems_nullptr))
    if problems_constructor:
        errors.append(
            output_api.PresubmitError(
                'The following files use explicit std::unique_ptr constructor. '
                'Use std::make_unique<T>() instead, or use base::WrapUnique if '
                'std::make_unique is not an option.', problems_constructor))
    return errors


def CheckUserActionUpdate(input_api, output_api):
    """Checks if any new user action has been added."""
    if any('actions.xml' == input_api.os_path.basename(f)
           for f in input_api.LocalPaths()):
        # If actions.xml is already included in the changelist, the PRESUBMIT
        # for actions.xml will do a more complete presubmit check.
        return []

    file_inclusion_pattern = [r'.*\.(cc|mm)$']
    files_to_skip = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
                     input_api.DEFAULT_FILES_TO_SKIP)
    file_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)

    action_re = r'[^a-zA-Z]UserMetricsAction\("([^"]*)'
    current_actions = None
    for f in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in f.ChangedContents():
            match = input_api.re.search(action_re, line)
            if match:
                # Loads contents in tools/metrics/actions/actions.xml to memory. It's
                # loaded only once.
                if not current_actions:
                    with open('tools/metrics/actions/actions.xml',
                              encoding='utf-8') as actions_f:
                        current_actions = actions_f.read()
                # Search for the matched user action name in |current_actions|.
                for action_name in match.groups():
                    action = 'name="{0}"'.format(action_name)
                    if action not in current_actions:
                        return [
                            output_api.PresubmitPromptWarning(
                                'File %s line %d: %s is missing in '
                                'tools/metrics/actions/actions.xml. Please run '
                                'tools/metrics/actions/extract_actions.py to update.'
                                % (f.LocalPath(), line_num, action_name))
                        ]
    return []


def _ImportJSONCommentEater(input_api):
    import sys
    sys.path = sys.path + [
        input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                               'json_comment_eater')
    ]
    import json_comment_eater
    return json_comment_eater


def _GetJSONParseError(input_api, filename, eat_comments=True):
    try:
        contents = input_api.ReadFile(filename)
        if eat_comments:
            json_comment_eater = _ImportJSONCommentEater(input_api)
            contents = json_comment_eater.Nom(contents)

        input_api.json.loads(contents)
    except ValueError as e:
        return e
    return None


def _GetIDLParseError(input_api, filename):
    try:
        contents = input_api.ReadFile(filename)
        for i, char in enumerate(contents):
            if not char.isascii():
                return (
                    'Non-ascii character "%s" (ord %d) found at offset %d.' %
                    (char, ord(char), i))
        idl_schema = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                            'tools', 'json_schema_compiler',
                                            'idl_schema.py')
        process = input_api.subprocess.Popen(
            [input_api.python3_executable, idl_schema],
            stdin=input_api.subprocess.PIPE,
            stdout=input_api.subprocess.PIPE,
            stderr=input_api.subprocess.PIPE,
            universal_newlines=True)
        (_, error) = process.communicate(input=contents)
        return error or None
    except ValueError as e:
        return e


def CheckParseErrors(input_api, output_api):
    """Check that IDL and JSON files do not contain syntax errors."""
    actions = {
        '.idl': _GetIDLParseError,
        '.json': _GetJSONParseError,
    }
    # Most JSON files are preprocessed and support comments, but these do not.
    json_no_comments_patterns = [
        r'^testing/',
    ]
    # Only run IDL checker on files in these directories.
    idl_included_patterns = [
        r'^chrome/common/extensions/api/',
        r'^extensions/common/api/',
    ]

    def get_action(affected_file):
        filename = affected_file.LocalPath()
        return actions.get(input_api.os_path.splitext(filename)[1])

    def FilterFile(affected_file):
        action = get_action(affected_file)
        if not action:
            return False
        path = affected_file.UnixLocalPath()

        if _MatchesFile(input_api,
                        _KNOWN_TEST_DATA_AND_INVALID_JSON_FILE_PATTERNS, path):
            return False

        if (action == _GetIDLParseError
                and not _MatchesFile(input_api, idl_included_patterns, path)):
            return False
        return True

    results = []
    for affected_file in input_api.AffectedFiles(file_filter=FilterFile,
                                                 include_deletes=False):
        action = get_action(affected_file)
        kwargs = {}
        if (action == _GetJSONParseError
                and _MatchesFile(input_api, json_no_comments_patterns,
                                 affected_file.UnixLocalPath())):
            kwargs['eat_comments'] = False
        parse_error = action(input_api, affected_file.AbsoluteLocalPath(),
                             **kwargs)
        if parse_error:
            results.append(
                output_api.PresubmitError(
                    '%s could not be parsed: %s' %
                    (affected_file.LocalPath(), parse_error)))
    return results


def CheckJavaStyle(input_api, output_api):
    """Runs checkstyle on changed java files and returns errors if any exist."""

    # Return early if no java files were modified.
    if not any(
            _IsJavaFile(input_api, f.LocalPath())
            for f in input_api.AffectedFiles()):
        return []

    import sys
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                                   'android', 'checkstyle')
        ]
        import checkstyle
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    return checkstyle.run_presubmit(input_api,
                                    output_api,
                                    files_to_skip=_EXCLUDED_PATHS +
                                    input_api.DEFAULT_FILES_TO_SKIP)


def CheckPythonDevilInit(input_api, output_api):
    """Checks to make sure devil is initialized correctly in python scripts."""
    script_common_initialize_pattern = input_api.re.compile(
        r'script_common\.InitializeEnvironment\(')
    devil_env_config_initialize = input_api.re.compile(
        r'devil_env\.config\.Initialize\(')

    errors = []

    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=(_EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP + (
            r'^build/android/devil_chromium\.py',
            r'^tools/bisect-builds\.py',
            r'^third_party/.*',
        )),
        files_to_check=[r'.*\.py$'])

    for f in input_api.AffectedSourceFiles(sources):
        for line_num, line in f.ChangedContents():
            if (script_common_initialize_pattern.search(line)
                    or devil_env_config_initialize.search(line)):
                errors.append('%s:%d' % (f.LocalPath(), line_num))

    results = []

    if errors:
        results.append(
            output_api.PresubmitError(
                'Devil initialization should always be done using '
                'devil_chromium.Initialize() in the chromium project, to use better '
                'defaults for dependencies (ex. up-to-date version of adb).',
                errors))

    return results


def _MatchesFile(input_api, patterns, path):
    for pattern in patterns:
        if input_api.re.search(pattern, path):
            return True
    return False


def _ChangeHasSecurityReviewer(input_api, owners_file):
    """Returns True iff the CL has a reviewer from SECURITY_OWNERS.

    Args:
        input_api: The presubmit input API.
        owners_file: OWNERS file with required reviewers. Typically, this is
        something like ipc/SECURITY_OWNERS.

    Note: if the presubmit is running for commit rather than for upload, this
    only returns True if a security reviewer has also approved the CL.
    """
    # Owners-Override should bypass all additional OWNERS enforcement checks.
    # A CR+1 vote will still be required to land this change.
    if (input_api.change.issue and input_api.gerrit.IsOwnersOverrideApproved(
            input_api.change.issue)):
        return True

    _, reviewers = (input_api.canned_checks.GetCodereviewOwnerAndReviewers(
        input_api,
        None,
        approval_needed=input_api.is_committing and not input_api.dry_run))

    security_owners = input_api.owners_client.ListOwners(owners_file)
    return any(owner in reviewers for owner in security_owners)


@dataclasses.dataclass
class _SecurityProblemWithItems:
    problem: str
    items: Sequence[str]


@dataclasses.dataclass
class _MissingSecurityOwnersResult:
    owners_file_problems: Sequence[_SecurityProblemWithItems]
    has_security_sensitive_files: bool
    missing_reviewer_problem: Optional[_SecurityProblemWithItems]


def _FindMissingSecurityOwners(
    input_api,
    file_patterns: Sequence[str],
    excluded_patterns: Sequence[str],
    required_owners_file: str,
    custom_rule_function: Optional[Callable] = None
) -> _MissingSecurityOwnersResult:
    """Find OWNERS files missing per-file rules for security-sensitive files.

    Args:
        input_api: the PRESUBMIT input API object.
        file_patterns: basename patterns that require a corresponding per-file
            security restriction.
        excluded_patterns: path patterns that should be exempted from
            requiring a security restriction.
        required_owners_file: path to the required OWNERS file, e.g.
            ipc/SECURITY_OWNERS
        cc_alias: If not None, email that will be CCed automatically if the
            change contains security-sensitive files, as determined by
            `file_patterns` and `excluded_patterns`.
        custom_rule_function: If not None, will be called with `input_api` and
            the current file under consideration. Returning True will add an
            exact match per-file rule check for the current file.
    """

    # `to_check` is a mapping of an OWNERS file path to Patterns.
    #
    # Patterns is a dictionary mapping glob patterns (suitable for use in
    # per-file rules) to a PatternEntry.
    #
    # PatternEntry is a dictionary with two keys:
    # - 'files': the files that are matched by this pattern
    # - 'rules': the per-file rules needed for this pattern
    #
    # For example, if we expect OWNERS file to contain rules for *.mojom and
    # *_struct_traits*.*, Patterns might look like this:
    # {
    #   '*.mojom': {
    #     'files': ...,
    #     'rules': [
    #       'per-file *.mojom=set noparent',
    #       'per-file *.mojom=file://ipc/SECURITY_OWNERS',
    #     ],
    #   },
    #   '*_struct_traits*.*': {
    #     'files': ...,
    #     'rules': [
    #       'per-file *_struct_traits*.*=set noparent',
    #       'per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS',
    #     ],
    #   },
    # }
    to_check = {}
    files_to_review = []

    def AddPatternToCheck(file, pattern):
        owners_file = input_api.os_path.join(
            input_api.os_path.dirname(file.LocalPath()), 'OWNERS')
        if owners_file not in to_check:
            to_check[owners_file] = {}
        if pattern not in to_check[owners_file]:
            to_check[owners_file][pattern] = {
                'files': [],
                'rules': [
                    f'per-file {pattern}=set noparent',
                    f'per-file {pattern}=file://{required_owners_file}',
                ]
            }
        to_check[owners_file][pattern]['files'].append(file.LocalPath())
        files_to_review.append(file.LocalPath())

    # Only enforce security OWNERS rules for a directory if that directory has a
    # file that matches `file_patterns`. For example, if a directory only
    # contains *.mojom files and no *_messages*.h files, the check should only
    # ensure that rules for *.mojom files are present.
    for file in input_api.AffectedFiles(include_deletes=False):
        file_basename = input_api.os_path.basename(file.LocalPath())
        if custom_rule_function is not None and custom_rule_function(
                input_api, file):
            AddPatternToCheck(file, file_basename)
            continue

        if any(
                input_api.fnmatch.fnmatch(file.LocalPath(), pattern)
                for pattern in excluded_patterns):
            continue

        for pattern in file_patterns:
            # Unlike `excluded_patterns`, `file_patterns` is checked only against the
            # file's basename.
            if input_api.fnmatch.fnmatch(file_basename, pattern):
                AddPatternToCheck(file, pattern)
                break

    has_security_sensitive_files = bool(to_check)

    # Check if any newly added lines in OWNERS files intersect with required
    # per-file OWNERS lines. If so, ensure that a security reviewer is included.
    # This is a hack, but is needed because the OWNERS check (by design) ignores
    # new OWNERS entries; otherwise, a non-owner could add someone as a new
    # OWNER and have that newly-added OWNER self-approve their own addition.
    newly_covered_files = []
    for file in input_api.AffectedFiles(include_deletes=False):
        if not file.LocalPath() in to_check:
            continue
        for _, line in file.ChangedContents():
            for _, entry in to_check[file.LocalPath()].items():
                if line in entry['rules']:
                    newly_covered_files.extend(entry['files'])

    missing_reviewer_problems = None
    if newly_covered_files and not _ChangeHasSecurityReviewer(
            input_api, required_owners_file):
        missing_reviewer_problems = _SecurityProblemWithItems(
            f'Review from an owner in {required_owners_file} is required for '
            'the following newly-added files:',
            [f'{file}' for file in sorted(set(newly_covered_files))])

    # Go through the OWNERS files to check, filtering out rules that are already
    # present in that OWNERS file.
    for owners_file, patterns in to_check.items():
        try:
            lines = set(
                input_api.ReadFile(
                    input_api.os_path.join(input_api.change.RepositoryRoot(),
                                           owners_file)).splitlines())
            for entry in patterns.values():
                entry['rules'] = [
                    rule for rule in entry['rules'] if rule not in lines
                ]
        except IOError:
            # No OWNERS file, so all the rules are definitely missing.
            continue

    # All the remaining lines weren't found in OWNERS files, so emit an error.
    owners_file_problems = []

    for owners_file, patterns in to_check.items():
        missing_lines = []
        files = []
        for _, entry in patterns.items():
            files.extend(entry['files'])
            missing_lines.extend(entry['rules'])
        if missing_lines:
            joined_missing_lines = '\n'.join(line for line in missing_lines)
            owners_file_problems.append(
                _SecurityProblemWithItems(
                    'Found missing OWNERS lines for security-sensitive files. '
                    f'Please add the following lines to {owners_file}:\n'
                    f'{joined_missing_lines}\n\nTo ensure security review for:',
                    files))

    return _MissingSecurityOwnersResult(owners_file_problems,
                                        has_security_sensitive_files,
                                        missing_reviewer_problems)


def _CheckChangeForIpcSecurityOwners(input_api):
    # Whether or not a file affects IPC is (mostly) determined by a simple list
    # of filename patterns.
    file_patterns = [
        # Legacy IPC:
        '*_messages.cc',
        '*_messages*.h',
        '*_param_traits*.*',
        # Mojo IPC:
        '*.mojom',
        '*_mojom_traits*.*',
        '*_type_converter*.*',
        # Android native IPC:
        '*.aidl',
    ]

    excluded_patterns = [
        # These third_party directories do not contain IPCs, but contain files
        # matching the above patterns, which trigger false positives.
        'third_party/crashpad/*',
        'third_party/blink/renderer/platform/bindings/*',
        'third_party/protobuf/*',
        'third_party/win_build_output/*',
        # Enum-only mojoms used for web metrics, so no security review needed.
        'third_party/blink/public/mojom/use_counter/metrics/*',
    ]

    def IsMojoServiceManifestFile(input_api, file):
        manifest_pattern = input_api.re.compile(r'manifests?\.(cc|h)$')
        test_manifest_pattern = input_api.re.compile(
            r'test_manifests?\.(cc|h)')
        if not manifest_pattern.search(file.LocalPath()):
            return False

        if test_manifest_pattern.search(file.LocalPath()):
            return False

        # All actual service manifest files should contain at least one
        # qualified reference to service_manager::Manifest.
        return any('service_manager::Manifest' in line
                   for line in file.NewContents())

    return _FindMissingSecurityOwners(
        input_api,
        file_patterns,
        excluded_patterns,
        'ipc/SECURITY_OWNERS',
        custom_rule_function=IsMojoServiceManifestFile)


def _CheckChangeForFuchsiaSecurityOwners(input_api):
    file_patterns = [
        # Component specifications.
        '*.cml',  # Component Framework v2.
        '*.cmx',  # Component Framework v1.

        # Fuchsia IDL protocol specifications.
        '*.fidl',
    ]

    # Don't check for owners files for changes in these directories.
    excluded_patterns = [
        'third_party/crashpad/*',
    ]

    return _FindMissingSecurityOwners(input_api, file_patterns,
                                      excluded_patterns,
                                      'build/fuchsia/SECURITY_OWNERS')


def CheckSecurityOwners(input_api, output_api):
    """Checks that various security-sensitive files have an IPC OWNERS rule."""
    ipc_results = _CheckChangeForIpcSecurityOwners(input_api)
    fuchsia_results = _CheckChangeForFuchsiaSecurityOwners(input_api)

    if ipc_results.has_security_sensitive_files:
        output_api.AppendCC('ipc-security-reviews@chromium.org')

    results = []

    missing_reviewer_problems = []
    if ipc_results.missing_reviewer_problem:
        missing_reviewer_problems.append(ipc_results.missing_reviewer_problem)
    if fuchsia_results.missing_reviewer_problem:
        missing_reviewer_problems.append(
            fuchsia_results.missing_reviewer_problem)

    # Missing reviewers are an error unless there's no issue number
    # associated with this branch; in that case, the presubmit is being run
    # with --all or --files.
    #
    # Note that upload should never be an error; otherwise, it would be
    # impossible to upload changes at all.
    if input_api.is_committing and input_api.change.issue:
        make_presubmit_message = output_api.PresubmitError
    else:
        make_presubmit_message = output_api.PresubmitNotifyResult
    for problem in missing_reviewer_problems:
        results.append(
            make_presubmit_message(problem.problem, items=problem.items))

    owners_file_problems = []
    owners_file_problems.extend(ipc_results.owners_file_problems)
    owners_file_problems.extend(fuchsia_results.owners_file_problems)

    for problem in owners_file_problems:
        # Missing per-file rules are always an error. While swarming and caching
        # means that uploading a patchset with updated OWNERS files and sending
        # it to the CQ again should not have a large incremental cost, it is
        # still frustrating to discover the error only after the change has
        # already been uploaded.
        results.append(
            output_api.PresubmitError(problem.problem, items=problem.items))

    return results


def _GetFilesUsingSecurityCriticalFunctions(input_api):
    """Checks affected files for changes to security-critical calls. This
    function checks the full change diff, to catch both additions/changes
    and removals.

    Returns a dict keyed by file name, and the value is a set of detected
    functions.
    """
    # Map of function pretty name (displayed in an error) to the pattern to
    # match it with.
    _PATTERNS_TO_CHECK = {
        'content::GetServiceSandboxType<>()': 'GetServiceSandboxType\\<'
    }
    _PATTERNS_TO_CHECK = {
        k: input_api.re.compile(v)
        for k, v in _PATTERNS_TO_CHECK.items()
    }

    # We don't want to trigger on strings within this file.
    def presubmit_file_filter(f):
        return 'PRESUBMIT.py' != input_api.os_path.split(f.LocalPath())[1]

    # Scan all affected files for changes touching _FUNCTIONS_TO_CHECK.
    files_to_functions = {}
    for f in input_api.AffectedFiles(file_filter=presubmit_file_filter):
        diff = f.GenerateScmDiff()
        for line in diff.split('\n'):
            # Not using just RightHandSideLines() because removing a
            # call to a security-critical function can be just as important
            # as adding or changing the arguments.
            if line.startswith('-') or (line.startswith('+')
                                        and not line.startswith('++')):
                for name, pattern in _PATTERNS_TO_CHECK.items():
                    if pattern.search(line):
                        path = f.LocalPath()
                        if not path in files_to_functions:
                            files_to_functions[path] = set()
                        files_to_functions[path].add(name)
    return files_to_functions


def CheckSecurityChanges(input_api, output_api):
    """Checks that changes involving security-critical functions are reviewed
    by the security team.
    """
    files_to_functions = _GetFilesUsingSecurityCriticalFunctions(input_api)
    if not files_to_functions:
        return []

    owners_file = 'ipc/SECURITY_OWNERS'
    if _ChangeHasSecurityReviewer(input_api, owners_file):
        return []

    msg = ('The following files change calls to security-sensitive functions\n'
           'that need to be reviewed by {}.\n'.format(owners_file))
    for path, names in files_to_functions.items():
        msg += '  {}\n'.format(path)
        for name in names:
            msg += '    {}\n'.format(name)
        msg += '\n'

    if input_api.is_committing:
        output = output_api.PresubmitError
    else:
        output = output_api.PresubmitNotifyResult
    return [output(msg)]


def CheckSetNoParent(input_api, output_api):
    """Checks that set noparent is only used together with an OWNERS file in
       //build/OWNERS.setnoparent (see also
       //docs/code_reviews.md#owners-files-details)
    """
    # Return early if no OWNERS files were modified.
    if not any(f.LocalPath().endswith('OWNERS')
               for f in input_api.AffectedFiles(include_deletes=False)):
        return []

    errors = []

    allowed_owners_files_file = 'build/OWNERS.setnoparent'
    allowed_owners_files = set()
    with open(allowed_owners_files_file, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            allowed_owners_files.add(line)

    per_file_pattern = input_api.re.compile('per-file (.+)=(.+)')

    for f in input_api.AffectedFiles(include_deletes=False):
        if not f.LocalPath().endswith('OWNERS'):
            continue

        found_owners_files = set()
        found_set_noparent_lines = dict()

        # Parse the OWNERS file.
        for lineno, line in enumerate(f.NewContents(), 1):
            line = line.strip()
            if line.startswith('set noparent'):
                found_set_noparent_lines[''] = lineno
            if line.startswith('file://'):
                if line in allowed_owners_files:
                    found_owners_files.add('')
            if line.startswith('per-file'):
                match = per_file_pattern.match(line)
                if match:
                    glob = match.group(1).strip()
                    directive = match.group(2).strip()
                    if directive == 'set noparent':
                        found_set_noparent_lines[glob] = lineno
                    if directive.startswith('file://'):
                        if directive in allowed_owners_files:
                            found_owners_files.add(glob)

        # Check that every set noparent line has a corresponding file:// line
        # listed in build/OWNERS.setnoparent. An exception is made for top level
        # directories since src/OWNERS shouldn't review them.
        linux_path = f.UnixLocalPath()
        if (linux_path.count('/') != 1
                and (not linux_path in _EXCLUDED_SET_NO_PARENT_PATHS)):
            for set_noparent_line in found_set_noparent_lines:
                if set_noparent_line in found_owners_files:
                    continue
                errors.append(
                    '  %s:%d' %
                    (linux_path, found_set_noparent_lines[set_noparent_line]))

    results = []
    if errors:
        if input_api.is_committing:
            output = output_api.PresubmitError
        else:
            output = output_api.PresubmitPromptWarning
        results.append(
            output(
                'Found the following "set noparent" restrictions in OWNERS files that '
                'do not include owners from build/OWNERS.setnoparent:',
                long_text='\n\n'.join(errors)))
    return results


def CheckUselessForwardDeclarations(input_api, output_api):
    """Checks that added or removed lines in non third party affected
       header files do not lead to new useless class or struct forward
       declaration.
    """
    results = []
    class_pattern = input_api.re.compile(r'^class\s+(\w+);$',
                                         input_api.re.MULTILINE)
    struct_pattern = input_api.re.compile(r'^struct\s+(\w+);$',
                                          input_api.re.MULTILINE)
    for f in input_api.AffectedFiles(include_deletes=False):
        local_path = f.UnixLocalPath()
        if (local_path.startswith('third_party')
                and not local_path.startswith('third_party/blink')):
            continue

        if not local_path.endswith('.h'):
            continue

        contents = input_api.ReadFile(f)
        fwd_decls = input_api.re.findall(class_pattern, contents)
        fwd_decls.extend(input_api.re.findall(struct_pattern, contents))

        useless_fwd_decls = []
        for decl in fwd_decls:
            count = sum(1 for _ in input_api.re.finditer(
                r'\b%s\b' % input_api.re.escape(decl), contents))
            if count == 1:
                useless_fwd_decls.append(decl)

        if not useless_fwd_decls:
            continue

        for line in f.GenerateScmDiff().splitlines():
            if (line.startswith('-') and not line.startswith('--')
                    or line.startswith('+') and not line.startswith('++')):
                for decl in useless_fwd_decls:
                    if input_api.re.search(r'\b%s\b' % decl, line[1:]):
                        results.append(
                            output_api.PresubmitPromptWarning(
                                '%s: %s forward declaration is no longer needed'
                                % (f.LocalPath(), decl)))
                        useless_fwd_decls.remove(decl)

    return results


def _CheckAndroidDebuggableBuild(input_api, output_api):
    """Checks that code uses BuildInfo.isDebugAndroid() instead of
       Build.TYPE.equals('') or ''.equals(Build.TYPE) to check if
       this is a debuggable build of Android.
    """
    build_type_check_pattern = input_api.re.compile(
        r'\bBuild\.TYPE\.equals\(|\.equals\(\s*\bBuild\.TYPE\)')

    errors = []

    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=(
            _EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + input_api.
            DEFAULT_FILES_TO_SKIP + (
                r'^android_webview/support_library/boundary_interfaces/',
                r'^chrome/android/webapk/.*',
                r'^third_party/.*',
                r'tools/android/customtabs_benchmark/.*',
                r'webview/chromium/License.*',
            )),
        files_to_check=[r'.*\.java$'])

    for f in input_api.AffectedSourceFiles(sources):
        for line_num, line in f.ChangedContents():
            if build_type_check_pattern.search(line):
                errors.append('%s:%d' % (f.LocalPath(), line_num))

    results = []

    if errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Build.TYPE.equals or .equals(Build.TYPE) usage is detected.'
                ' Please use BuildInfo.isDebugAndroid() instead.', errors))

    return results


# TODO: add unit tests
def _CheckAndroidToastUsage(input_api, output_api):
    """Checks that code uses org.chromium.ui.widget.Toast instead of
       android.widget.Toast (Chromium Toast doesn't force hardware
       acceleration on low-end devices, saving memory).
    """
    toast_import_pattern = input_api.re.compile(
        r'^import android\.widget\.Toast;$')

    errors = []

    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + input_api.
                       DEFAULT_FILES_TO_SKIP +
                       (r'^chromecast/.*', r'^remoting/.*')),
        files_to_check=[r'.*\.java$'])

    for f in input_api.AffectedSourceFiles(sources):
        for line_num, line in f.ChangedContents():
            if toast_import_pattern.search(line):
                errors.append('%s:%d' % (f.LocalPath(), line_num))

    results = []

    if errors:
        results.append(
            output_api.PresubmitError(
                'android.widget.Toast usage is detected. Android toasts use hardware'
                ' acceleration, and can be\ncostly on low-end devices. Please use'
                ' org.chromium.ui.widget.Toast instead.\n'
                'Contact dskiba@chromium.org if you have any questions.',
                errors))

    return results


def _CheckAndroidCrLogUsage(input_api, output_api):
    """Checks that new logs using org.chromium.base.Log:
      - Are using 'TAG' as variable name for the tags (warn)
      - Are using a tag that is shorter than 20 characters (error)
    """

    # Do not check format of logs in the given files
    cr_log_check_excluded_paths = [
        # //chrome/android/webapk cannot depend on //base
        r'^chrome/android/webapk/.*',
        # WebView license viewer code cannot depend on //base; used in stub APK.
        r'^android_webview/glue/java/src/com/android/'
        r'webview/chromium/License.*',
        # The customtabs_benchmark is a small app that does not depend on Chromium
        # java pieces.
        r'tools/android/customtabs_benchmark/.*',
    ]

    cr_log_import_pattern = input_api.re.compile(
        r'^import org\.chromium\.base\.Log;$', input_api.re.MULTILINE)
    class_in_base_pattern = input_api.re.compile(
        r'^package org\.chromium\.base;$', input_api.re.MULTILINE)
    has_some_log_import_pattern = input_api.re.compile(r'^import .*\.Log;$',
                                                       input_api.re.MULTILINE)
    # Extract the tag from lines like `Log.d(TAG, "*");` or `Log.d("TAG", "*");`
    log_call_pattern = input_api.re.compile(r'\bLog\.\w\((?P<tag>\"?\w+)')
    log_decl_pattern = input_api.re.compile(
        r'static final String TAG = "(?P<name>(.*))"')
    rough_log_decl_pattern = input_api.re.compile(r'\bString TAG\s*=')

    REF_MSG = ('See docs/android_logging.md for more info.')
    sources = lambda x: input_api.FilterSourceFile(
        x,
        files_to_check=[r'.*\.java$'],
        files_to_skip=cr_log_check_excluded_paths)

    tag_decl_errors = []
    tag_length_errors = []
    tag_errors = []
    tag_with_dot_errors = []
    util_log_errors = []

    for f in input_api.AffectedSourceFiles(sources):
        file_content = input_api.ReadFile(f)
        has_modified_logs = False
        # Per line checks
        if (cr_log_import_pattern.search(file_content)
                or (class_in_base_pattern.search(file_content)
                    and not has_some_log_import_pattern.search(file_content))):
            # Checks to run for files using cr log
            for line_num, line in f.ChangedContents():
                if rough_log_decl_pattern.search(line):
                    has_modified_logs = True

                # Check if the new line is doing some logging
                match = log_call_pattern.search(line)
                if match:
                    has_modified_logs = True

                    # Make sure it uses "TAG"
                    if not match.group('tag') == 'TAG':
                        tag_errors.append('%s:%d' % (f.LocalPath(), line_num))
        else:
            # Report non cr Log function calls in changed lines
            for line_num, line in f.ChangedContents():
                if (log_call_pattern.search(line)
                        or has_some_log_import_pattern.search(line)):
                    util_log_errors.append('%s:%d' % (f.LocalPath(), line_num))

        # Per file checks
        if has_modified_logs:
            # Make sure the tag is using the "cr" prefix and is not too long
            match = log_decl_pattern.search(file_content)
            tag_name = match.group('name') if match else None
            if not tag_name:
                tag_decl_errors.append(f.LocalPath())
            elif len(tag_name) > 20:
                tag_length_errors.append(f.LocalPath())
            elif '.' in tag_name:
                tag_with_dot_errors.append(f.LocalPath())

    results = []
    if tag_decl_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Please define your tags using the suggested format: .\n'
                '"private static final String TAG = "<package tag>".\n'
                'They will be prepended with "cr_" automatically.\n' + REF_MSG,
                tag_decl_errors))

    if tag_length_errors:
        results.append(
            output_api.PresubmitError(
                'The tag length is restricted by the system to be at most '
                '20 characters.\n' + REF_MSG, tag_length_errors))

    if tag_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Please use a variable named "TAG" for your log tags.\n' +
                REF_MSG, tag_errors))

    if util_log_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Please use org.chromium.base.Log for new logs.\n' + REF_MSG,
                util_log_errors))

    if tag_with_dot_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'Dot in log tags cause them to be elided in crash reports.\n' +
                REF_MSG, tag_with_dot_errors))

    return results


def _CheckAndroidTestAnnotationUsage(input_api, output_api):
    """Checks that android.test.suitebuilder.annotation.* is no longer used."""
    deprecated_annotation_import_pattern = input_api.re.compile(
        r'^import android\.test\.suitebuilder\.annotation\..*;',
        input_api.re.MULTILINE)
    sources = lambda x: input_api.FilterSourceFile(
        x, files_to_check=[r'.*\.java$'], files_to_skip=None)
    errors = []
    for f in input_api.AffectedFiles(file_filter=sources):
        for line_num, line in f.ChangedContents():
            if deprecated_annotation_import_pattern.search(line):
                errors.append('%s:%d' % (f.LocalPath(), line_num))

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'Annotations in android.test.suitebuilder.annotation have been'
                ' deprecated since API level 24. Please use androidx.test.filters'
                ' from //third_party/androidx:androidx_test_runner_java instead.'
                ' Contact yolandyan@chromium.org if you have any questions.',
                errors))
    return results


def _CheckAndroidNewMdpiAssetLocation(input_api, output_api):
    """Checks if MDPI assets are placed in a correct directory."""
    file_filter = lambda f: (f.UnixLocalPath().endswith('.png') and
                             ('/res/drawable/' in f.UnixLocalPath() or
                              '/res/drawable-ldrtl/' in f.UnixLocalPath()))
    errors = []
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=file_filter):
        errors.append('    %s' % f.LocalPath())

    results = []
    if errors:
        results.append(
            output_api.PresubmitError(
                'MDPI assets should be placed in /res/drawable-mdpi/ or '
                '/res/drawable-ldrtl-mdpi/\ninstead of /res/drawable/ and'
                '/res/drawable-ldrtl/.\n'
                'Contact newt@chromium.org if you have questions.', errors))
    return results


def _CheckAndroidWebkitImports(input_api, output_api):
    """Checks that code uses org.chromium.base.Callback instead of
       android.webview.ValueCallback except in the WebView glue layer.
    """
    valuecallback_import_pattern = input_api.re.compile(
        r'^import android\.webkit\.ValueCallback;$')

    errors = []

    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + input_api.
                       DEFAULT_FILES_TO_SKIP + (
                           r'^android_webview/glue/.*',
                           r'^android_webview/support_library/.*',
                       )),
        files_to_check=[r'.*\.java$'])

    for f in input_api.AffectedSourceFiles(sources):
        for line_num, line in f.ChangedContents():
            if valuecallback_import_pattern.search(line):
                errors.append('%s:%d' % (f.LocalPath(), line_num))

    results = []

    if errors:
        results.append(
            output_api.PresubmitError(
                'android.webkit.ValueCallback usage is detected outside of the glue'
                ' layer. To stay compatible with the support library, android.webkit.*'
                ' classes should only be used inside the glue layer and'
                ' org.chromium.base.Callback should be used instead.', errors))

    return results


def _CheckAndroidXmlStyle(input_api, output_api, is_check_on_upload):
    """Checks Android XML styles """

    # Return early if no relevant files were modified.
    if not any(
            _IsXmlOrGrdFile(input_api, f.LocalPath())
            for f in input_api.AffectedFiles(include_deletes=False)):
        return []

    import sys
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                                   'android', 'checkxmlstyle')
        ]
        import checkxmlstyle
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    if is_check_on_upload:
        return checkxmlstyle.CheckStyleOnUpload(input_api, output_api)
    else:
        return checkxmlstyle.CheckStyleOnCommit(input_api, output_api)


def _CheckAndroidInfoBarDeprecation(input_api, output_api):
    """Checks Android Infobar Deprecation """

    import sys
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                                   'android', 'infobar_deprecation')
        ]
        import infobar_deprecation
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    return infobar_deprecation.CheckDeprecationOnUpload(input_api, output_api)


class _PydepsCheckerResult:

    def __init__(self, cmd, pydeps_path, process, old_contents):
        self._cmd = cmd
        self._pydeps_path = pydeps_path
        self._process = process
        self._old_contents = old_contents

    def GetError(self):
        """Returns an error message, or None."""
        import difflib
        new_contents = self._process.stdout.read().splitlines()[2:]
        if self._process.wait() != 0:
            # STDERR should already be printed.
            return 'Command failed: ' + self._cmd
        if self._old_contents != new_contents:
            diff = '\n'.join(
                difflib.context_diff(self._old_contents, new_contents))
            return ('File is stale: {}\n'
                    'Diff (apply to fix):\n'
                    '{}\n'
                    'To regenerate, run:\n\n'
                    '    {}').format(self._pydeps_path, diff, self._cmd)
        return None


class PydepsChecker:

    def __init__(self, input_api, pydeps_files):
        self._file_cache = {}
        self._input_api = input_api
        self._pydeps_files = pydeps_files

    def _LoadFile(self, path):
        """Returns the list of paths within a .pydeps file relative to //."""
        if path not in self._file_cache:
            with open(path, encoding='utf-8') as f:
                self._file_cache[path] = f.read()
        return self._file_cache[path]

    def _ComputeNormalizedPydepsEntries(self, pydeps_path):
        """Returns an iterable of paths within the .pydep, relativized to //."""
        pydeps_data = self._LoadFile(pydeps_path)
        uses_gn_paths = '--gn-paths' in pydeps_data
        entries = (l for l in pydeps_data.splitlines()
                   if not l.startswith('#'))
        if uses_gn_paths:
            # Paths look like: //foo/bar/baz
            return (e[2:] for e in entries)
        else:
            # Paths look like: path/relative/to/file.pydeps
            os_path = self._input_api.os_path
            pydeps_dir = os_path.dirname(pydeps_path)
            return (os_path.normpath(os_path.join(pydeps_dir, e))
                    for e in entries)

    def _CreateFilesToPydepsMap(self):
        """Returns a map of local_path -> list_of_pydeps."""
        ret = {}
        for pydep_local_path in self._pydeps_files:
            for path in self._ComputeNormalizedPydepsEntries(pydep_local_path):
                ret.setdefault(path, []).append(pydep_local_path)
        return ret

    def ComputeAffectedPydeps(self):
        """Returns an iterable of .pydeps files that might need regenerating."""
        affected_pydeps = set()
        file_to_pydeps_map = None
        for f in self._input_api.AffectedFiles(include_deletes=True):
            local_path = f.LocalPath()
            # Changes to DEPS can lead to .pydeps changes if any .py files are in
            # subrepositories. We can't figure out which files change, so re-check
            # all files.
            # Changes to print_python_deps.py affect all .pydeps.
            if local_path in ('DEPS', 'PRESUBMIT.py'
                              ) or local_path.endswith('print_python_deps.py'):
                return self._pydeps_files
            elif local_path.endswith('.pydeps'):
                if local_path in self._pydeps_files:
                    affected_pydeps.add(local_path)
            elif local_path.endswith('.py'):
                if file_to_pydeps_map is None:
                    file_to_pydeps_map = self._CreateFilesToPydepsMap()
                affected_pydeps.update(file_to_pydeps_map.get(local_path, ()))
        return affected_pydeps

    def DetermineIfStaleAsync(self, pydeps_path):
        """Runs print_python_deps.py to see if the files is stale."""
        import os

        old_pydeps_data = self._LoadFile(pydeps_path).splitlines()
        if old_pydeps_data:
            cmd = old_pydeps_data[1][1:].strip()
            if '--output' not in cmd:
                cmd += ' --output ' + pydeps_path
            old_contents = old_pydeps_data[2:]
        else:
            # A default cmd that should work in most cases (as long as pydeps filename
            # matches the script name) so that PRESUBMIT.py does not crash if pydeps
            # file is empty/new.
            cmd = 'build/print_python_deps.py {} --root={} --output={}'.format(
                pydeps_path[:-4], os.path.dirname(pydeps_path), pydeps_path)
            old_contents = []
        env = dict(os.environ)
        env['PYTHONDONTWRITEBYTECODE'] = '1'
        process = self._input_api.subprocess.Popen(
            cmd + ' --output ""',
            shell=True,
            env=env,
            stdout=self._input_api.subprocess.PIPE,
            encoding='utf-8')
        return _PydepsCheckerResult(cmd, pydeps_path, process, old_contents)


def _ParseGclientArgs():
    args = {}
    with open('build/config/gclient_args.gni', 'r') as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            attribute, value = line.split('=')
            args[attribute.strip()] = value.strip()
    return args


def CheckPydepsNeedsUpdating(input_api, output_api, checker_for_tests=None):
    """Checks if a .pydeps file needs to be regenerated."""
    # This check is for Python dependency lists (.pydeps files), and involves
    # paths not only in the PRESUBMIT.py, but also in the .pydeps files. It
    # doesn't work on Windows and Mac, so skip it on other platforms.
    if not input_api.platform.startswith('linux'):
        return []

    results = []
    # First, check for new / deleted .pydeps.
    for f in input_api.AffectedFiles(include_deletes=True):
        # Check whether we are running the presubmit check for a file in src.
        if f.LocalPath().endswith('.pydeps'):
            # f.LocalPath is relative to repo (src, or internal repo).
            # os_path.exists is relative to src repo.
            # Therefore if os_path.exists is true, it means f.LocalPath is relative
            # to src and we can conclude that the pydeps is in src.
            exists = input_api.os_path.exists(f.LocalPath())
            if f.Action() == 'D' and f.LocalPath() in _ALL_PYDEPS_FILES:
                results.append(
                    output_api.PresubmitError(
                        'Please update _ALL_PYDEPS_FILES within //PRESUBMIT.py to '
                        'remove %s' % f.LocalPath()))
            elif (f.Action() != 'D' and exists
                  and f.LocalPath() not in _ALL_PYDEPS_FILES):
                results.append(
                    output_api.PresubmitError(
                        'Please update _ALL_PYDEPS_FILES within //PRESUBMIT.py to '
                        'include %s' % f.LocalPath()))

    if results:
        return results

    try:
        parsed_args = _ParseGclientArgs()
    except FileNotFoundError:
        message = (
            'build/config/gclient_args.gni not found. Please make sure your '
            'workspace has been initialized with gclient sync.')
        import sys
        original_sys_path = sys.path
        try:
            sys.path = sys.path + [
                input_api.os_path.join(input_api.PresubmitLocalPath(),
                                       'third_party', 'depot_tools')
            ]
            import gclient_utils
            if gclient_utils.IsEnvCog():
                # Users will always hit this when they run presubmits before cog
                # workspace initialization finishes. The check shouldn't fail in
                # this case. This is an unavoidable workaround that's needed for
                # good presubmit UX for cog.
                results.append(output_api.PresubmitPromptWarning(message))
            else:
                results.append(output_api.PresubmitError(message))
            return results
        finally:
            # Restore sys.path to what it was before.
            sys.path = original_sys_path

    is_android = parsed_args.get('checkout_android', 'false') == 'true'
    checker = checker_for_tests or PydepsChecker(input_api, _ALL_PYDEPS_FILES)
    affected_pydeps = set(checker.ComputeAffectedPydeps())
    affected_android_pydeps = affected_pydeps.intersection(
        set(_ANDROID_SPECIFIC_PYDEPS_FILES))
    if affected_android_pydeps and not is_android:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You have changed python files that may affect pydeps for android\n'
                'specific scripts. However, the relevant presubmit check cannot be\n'
                'run because you are not using an Android checkout. To validate that\n'
                'the .pydeps are correct, re-run presubmit in an Android checkout, or\n'
                'use the android-internal-presubmit optional trybot.\n'
                'Possibly stale pydeps files:\n{}'.format(
                    '\n'.join(affected_android_pydeps))))

    all_pydeps = _ALL_PYDEPS_FILES if is_android else _GENERIC_PYDEPS_FILES
    pydeps_to_check = affected_pydeps.intersection(all_pydeps)
    # Process these concurrently, as each one takes 1-2 seconds.
    pydep_results = [checker.DetermineIfStaleAsync(p) for p in pydeps_to_check]
    for result in pydep_results:
        error_msg = result.GetError()
        if error_msg:
            results.append(output_api.PresubmitError(error_msg))

    return results


def CheckSingletonInHeaders(input_api, output_api):
    """Checks to make sure no header files have |Singleton<|."""

    def FileFilter(affected_file):
        # It's ok for base/memory/singleton.h to have |Singleton<|.
        files_to_skip = (_EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP +
                         (r'^base/memory/singleton\.h$',
                          r'^net/quic/platform/impl/quic_singleton_impl\.h$'))
        return input_api.FilterSourceFile(affected_file,
                                          files_to_skip=files_to_skip)

    pattern = input_api.re.compile(r'(?<!class\sbase::)Singleton\s*<')
    files = []
    for f in input_api.AffectedSourceFiles(FileFilter):
        if (f.LocalPath().endswith('.h') or f.LocalPath().endswith('.hxx')
                or f.LocalPath().endswith('.hpp')
                or f.LocalPath().endswith('.inl')):
            contents = input_api.ReadFile(f)
            for line in contents.splitlines(False):
                if (not line.lstrip().startswith('//')
                        and  # Strip C++ comment.
                        pattern.search(line)):
                    files.append(f)
                    break

    if files:
        return [
            output_api.PresubmitError(
                'Found base::Singleton<T> in the following header files.\n' +
                'Please move them to an appropriate source file so that the ' +
                'template gets instantiated in a single compilation unit.',
                files)
        ]
    return []


_DEPRECATED_CSS = [
    # Values
    ('-webkit-box', 'flex'),
    ('-webkit-inline-box', 'inline-flex'),
    ('-webkit-flex', 'flex'),
    ('-webkit-inline-flex', 'inline-flex'),
    ('-webkit-min-content', 'min-content'),
    ('-webkit-max-content', 'max-content'),

    # Properties
    ('-webkit-background-clip', 'background-clip'),
    ('-webkit-background-origin', 'background-origin'),
    ('-webkit-background-size', 'background-size'),
    ('-webkit-box-shadow', 'box-shadow'),
    ('-webkit-user-select', 'user-select'),

    # Functions
    ('-webkit-gradient', 'gradient'),
    ('-webkit-repeating-gradient', 'repeating-gradient'),
    ('-webkit-linear-gradient', 'linear-gradient'),
    ('-webkit-repeating-linear-gradient', 'repeating-linear-gradient'),
    ('-webkit-radial-gradient', 'radial-gradient'),
    ('-webkit-repeating-radial-gradient', 'repeating-radial-gradient'),
]


# TODO: add unit tests
def CheckNoDeprecatedCss(input_api, output_api):
    """ Make sure that we don't use deprecated CSS
        properties, functions or values. Our external
        documentation and iOS CSS for dom distiller
        (reader mode) are ignored by the hooks as it
        needs to be consumed by WebKit. """
    results = []
    file_inclusion_pattern = [r'.+\.css$']
    files_to_skip = (
        _EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
        input_api.DEFAULT_FILES_TO_SKIP +
        (  # Legacy CSS file using deprecated CSS.
            r'^chrome/browser/resources/chromeos/arc_support/cr_overlay.css$',
            r'^chrome/common/extensions/docs',
            r'^chrome/docs',
            # The NTP team prefers reserving -webkit-line-clamp for
            # ellipsis effect which can only be used with -webkit-box.
            r'ui/webui/resources/cr_components/most_visited/.*\.css$',
            r'ui/webui/resources/cr_components/searchbox/searchbox_match.css$')
    )
    file_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)
    for fpath in input_api.AffectedFiles(file_filter=file_filter):
        for line_num, line in fpath.ChangedContents():
            for (deprecated_value, value) in _DEPRECATED_CSS:
                if deprecated_value in line:
                    results.append(
                        output_api.PresubmitError(
                            '%s:%d: Use of deprecated CSS %s, use %s instead' %
                            (fpath.LocalPath(), line_num, deprecated_value,
                             value)))
    return results


def CheckForRelativeIncludes(input_api, output_api):
    bad_files = {}
    for f in input_api.AffectedFiles(include_deletes=False):
        if (f.UnixLocalPath().startswith('third_party')
                and not f.LocalPath().startswith('third_party/blink')):
            continue

        if not _IsCPlusPlusFile(input_api, f.LocalPath()):
            continue

        relative_includes = [
            line for _, line in f.ChangedContents()
            if '#include' in line and '../' in line
        ]
        if not relative_includes:
            continue
        bad_files[f.LocalPath()] = relative_includes

    if not bad_files:
        return []

    error_descriptions = []
    for file_path, bad_lines in bad_files.items():
        error_description = file_path
        for line in bad_lines:
            error_description += '\n    ' + line
        error_descriptions.append(error_description)

    results = []
    results.append(
        output_api.PresubmitError(
            'You added one or more relative #include paths (including "../").\n'
            'These shouldn\'t be used because they can be used to include headers\n'
            'from code that\'s not correctly specified as a dependency in the\n'
            'relevant BUILD.gn file(s).', error_descriptions))

    return results


def CheckForCcIncludes(input_api, output_api):
    """Check that nobody tries to include a cc file. It's a relatively
    common error which results in duplicate symbols in object
    files. This may not always break the build until someone later gets
    very confusing linking errors."""
    results = []
    for f in input_api.AffectedFiles(include_deletes=False):
        # We let third_party code do whatever it wants
        if (f.UnixLocalPath().startswith('third_party')
                and not f.LocalPath().startswith('third_party/blink')):
            continue

        if not _IsCPlusPlusFile(input_api, f.LocalPath()):
            continue

        for _, line in f.ChangedContents():
            if line.startswith('#include "'):
                included_file = line.split('"')[1]
                if _IsCPlusPlusFile(input_api, included_file):
                    # The most common naming for external files with C++ code,
                    # apart from standard headers, is to call them foo.inc, but
                    # Chromium sometimes uses foo-inc.cc so allow that as well.
                    if not included_file.endswith(('.h', '-inc.cc')):
                        results.append(
                            output_api.PresubmitError(
                                'Only header files or .inc files should be included in other\n'
                                'C++ files. Compiling the contents of a cc file more than once\n'
                                'will cause duplicate information in the build which may later\n'
                                'result in strange link_errors.\n' +
                                f.LocalPath() + ':\n    ' + line))

    return results


def _CheckWatchlistDefinitionsEntrySyntax(key, value, ast):
    if not isinstance(key, ast.Str):
        return 'Key at line %d must be a string literal' % key.lineno
    if not isinstance(value, ast.Dict):
        return 'Value at line %d must be a dict' % value.lineno
    if len(value.keys) != 1:
        return 'Dict at line %d must have single entry' % value.lineno
    if not isinstance(value.keys[0], ast.Str) or value.keys[0].s != 'filepath':
        return (
            'Entry at line %d must have a string literal \'filepath\' as key' %
            value.lineno)
    return None


def _CheckWatchlistsEntrySyntax(key, value, ast, email_regex):
    if not isinstance(key, ast.Str):
        return 'Key at line %d must be a string literal' % key.lineno
    if not isinstance(value, ast.List):
        return 'Value at line %d must be a list' % value.lineno
    for element in value.elts:
        if not isinstance(element, ast.Str):
            return 'Watchlist elements on line %d is not a string' % key.lineno
        if not email_regex.match(element.s):
            return ('Watchlist element on line %d doesn\'t look like a valid '
                    + 'email: %s') % (key.lineno, element.s)
    return None


def _CheckWATCHLISTSEntries(wd_dict, w_dict, input_api):
    mismatch_template = (
        'Mismatch between WATCHLIST_DEFINITIONS entry (%s) and WATCHLISTS '
        'entry (%s)')

    email_regex = input_api.re.compile(
        r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+$')

    ast = input_api.ast
    i = 0
    last_key = ''
    while True:
        if i >= len(wd_dict.keys):
            if i >= len(w_dict.keys):
                return None
            return mismatch_template % ('missing',
                                        'line %d' % w_dict.keys[i].lineno)
        elif i >= len(w_dict.keys):
            return (mismatch_template %
                    ('line %d' % wd_dict.keys[i].lineno, 'missing'))

        wd_key = wd_dict.keys[i]
        w_key = w_dict.keys[i]

        result = _CheckWatchlistDefinitionsEntrySyntax(wd_key,
                                                       wd_dict.values[i], ast)
        if result is not None:
            return 'Bad entry in WATCHLIST_DEFINITIONS dict: %s' % result

        result = _CheckWatchlistsEntrySyntax(w_key, w_dict.values[i], ast,
                                             email_regex)
        if result is not None:
            return 'Bad entry in WATCHLISTS dict: %s' % result

        if wd_key.s != w_key.s:
            return mismatch_template % ('%s at line %d' %
                                        (wd_key.s, wd_key.lineno),
                                        '%s at line %d' %
                                        (w_key.s, w_key.lineno))

        if wd_key.s < last_key:
            return (
                'WATCHLISTS dict is not sorted lexicographically at line %d and %d'
                % (wd_key.lineno, w_key.lineno))
        last_key = wd_key.s

        i = i + 1


def _CheckWATCHLISTSSyntax(expression, input_api):
    ast = input_api.ast
    if not isinstance(expression, ast.Expression):
        return 'WATCHLISTS file must contain a valid expression'
    dictionary = expression.body
    if not isinstance(dictionary, ast.Dict) or len(dictionary.keys) != 2:
        return 'WATCHLISTS file must have single dict with exactly two entries'

    first_key = dictionary.keys[0]
    first_value = dictionary.values[0]
    second_key = dictionary.keys[1]
    second_value = dictionary.values[1]

    if (not isinstance(first_key, ast.Str)
            or first_key.s != 'WATCHLIST_DEFINITIONS'
            or not isinstance(first_value, ast.Dict)):
        return ('The first entry of the dict in WATCHLISTS file must be '
                'WATCHLIST_DEFINITIONS dict')

    if (not isinstance(second_key, ast.Str) or second_key.s != 'WATCHLISTS'
            or not isinstance(second_value, ast.Dict)):
        return ('The second entry of the dict in WATCHLISTS file must be '
                'WATCHLISTS dict')

    return _CheckWATCHLISTSEntries(first_value, second_value, input_api)


def CheckWATCHLISTS(input_api, output_api):
    for f in input_api.AffectedFiles(include_deletes=False):
        if f.LocalPath() == 'WATCHLISTS':
            contents = input_api.ReadFile(f, 'r')

            try:
                # First, make sure that it can be evaluated.
                input_api.ast.literal_eval(contents)
                # Get an AST tree for it and scan the tree for detailed style checking.
                expression = input_api.ast.parse(contents,
                                                 filename='WATCHLISTS',
                                                 mode='eval')
            except ValueError as e:
                return [
                    output_api.PresubmitError('Cannot parse WATCHLISTS file',
                                              long_text=repr(e))
                ]
            except SyntaxError as e:
                return [
                    output_api.PresubmitError('Cannot parse WATCHLISTS file',
                                              long_text=repr(e))
                ]
            except TypeError as e:
                return [
                    output_api.PresubmitError('Cannot parse WATCHLISTS file',
                                              long_text=repr(e))
                ]

            result = _CheckWATCHLISTSSyntax(expression, input_api)
            if result is not None:
                return [output_api.PresubmitError(result)]
            break

    return []


def CheckGnRebasePath(input_api, output_api):
    """Checks that target_gen_dir is not used with "//" in rebase_path().

    Developers should use root_build_dir instead of "//" when using target_gen_dir because
    Chromium is sometimes built outside of the source tree.
    """

    def gn_files(f):
        return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gn', ))

    rebase_path_regex = input_api.re.compile(
        r'rebase_path\(("\$target_gen_dir"|target_gen_dir), ("/"|"//")\)')
    problems = []
    for f in input_api.AffectedSourceFiles(gn_files):
        for line_num, line in f.ChangedContents():
            if rebase_path_regex.search(line):
                problems.append('Absolute path in rebase_path() in %s:%d' %
                                (f.LocalPath(), line_num))

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Using an absolute path in rebase_path()',
                items=sorted(problems),
                long_text=(
                    'rebase_path() should use root_build_dir instead of "/" ',
                    'since builds can be initiated from outside of the source ',
                    'root.'))
        ]
    return []


def CheckGnGlobForward(input_api, output_api):
    """Checks that forward_variables_from(invoker, "*") follows best practices.

    As documented at //build/docs/writing_gn_templates.md
    """

    def gn_files(f):
        return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gni', ))

    problems = []
    for f in input_api.AffectedSourceFiles(gn_files):
        for line_num, line in f.ChangedContents():
            if 'forward_variables_from(invoker, "*")' in line:
                problems.append(
                    'Bare forward_variables_from(invoker, "*") in %s:%d' %
                    (f.LocalPath(), line_num))

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'forward_variables_from("*") without exclusions',
                items=sorted(problems),
                long_text=(
                    'The variables "visibility" and "test_only" should be '
                    'explicitly listed in forward_variables_from(). For more '
                    'details, see:\n'
                    'https://chromium.googlesource.com/chromium/src/+/HEAD/'
                    'build/docs/writing_gn_templates.md'
                    '#Using-forward_variables_from'))
        ]
    return []


def CheckNewHeaderWithoutGnChangeOnUpload(input_api, output_api):
    """Checks that newly added header files have corresponding GN changes.
    Note that this is only a heuristic. To be precise, run script:
    build/check_gn_headers.py.
    """

    def headers(f):
        return input_api.FilterSourceFile(
            f, files_to_check=(r'.+%s' % _HEADER_EXTENSIONS, ))

    new_headers = []
    for f in input_api.AffectedSourceFiles(headers):
        if f.Action() != 'A':
            continue
        new_headers.append(f.LocalPath())

    def gn_files(f):
        return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gn', ))

    all_gn_changed_contents = ''
    for f in input_api.AffectedSourceFiles(gn_files):
        for _, line in f.ChangedContents():
            all_gn_changed_contents += line

    problems = []
    for header in new_headers:
        basename = input_api.os_path.basename(header)
        if basename not in all_gn_changed_contents:
            problems.append(header)

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Missing GN changes for new header files',
                items=sorted(problems),
                long_text=
                'Please double check whether newly added header files need '
                'corresponding changes in gn or gni files.\nThis checking is only a '
                'heuristic. Run build/check_gn_headers.py to be precise.\n'
                'Read https://crbug.com/661774 for more info.')
        ]
    return []


def CheckCorrectProductNameInMessages(input_api, output_api):
    """Check that Chromium-branded strings don't include "Chrome" or vice versa.

    This assumes we won't intentionally reference one product from the other
    product.
    """
    all_problems = []
    test_cases = [{
        'filename_postfix': 'google_chrome_strings.grd',
        'correct_name': 'Chrome',
        'incorrect_name': 'Chromium',
    }, {
        'filename_postfix': 'google_chrome_strings.grd',
        'correct_name': 'Chrome',
        'incorrect_name': 'Chrome for Testing',
    }, {
        'filename_postfix': 'chromium_strings.grd',
        'correct_name': 'Chromium',
        'incorrect_name': 'Chrome',
    }]

    for test_case in test_cases:
        problems = []
        filename_filter = lambda x: x.LocalPath().endswith(test_case[
            'filename_postfix'])

        # Check each new line. Can yield false positives in multiline comments, but
        # easier than trying to parse the XML because messages can have nested
        # children, and associating message elements with affected lines is hard.
        for f in input_api.AffectedSourceFiles(filename_filter):
            for line_num, line in f.ChangedContents():
                if '<message' in line or '<!--' in line or '-->' in line:
                    continue
                if test_case['incorrect_name'] in line:
                    # Chrome for Testing is a special edge case: https://goo.gle/chrome-for-testing#bookmark=id.n1rat320av91
                    if (test_case['correct_name'] == 'Chromium'
                            and line.count('Chrome')
                            == line.count('Chrome for Testing')):
                        continue
                    problems.append('Incorrect product name in %s:%d' %
                                    (f.LocalPath(), line_num))

        if problems:
            message = (
                'Strings in %s-branded string files should reference "%s", not "%s"'
                % (test_case['correct_name'], test_case['correct_name'],
                   test_case['incorrect_name']))
            all_problems.append(
                output_api.PresubmitPromptWarning(message, items=problems))

    return all_problems


def CheckForTooLargeFiles(input_api, output_api):
    """Avoid large files, especially binary files, in the repository since
    git doesn't scale well for those. They will be in everyone's repo
    clones forever, forever making Chromium slower to clone and work
    with."""

    # Uploading files to cloud storage is not trivial so we don't want
    # to set the limit too low, but the upper limit for "normal" large
    # files seems to be 1-2 MB, with a handful around 5-8 MB, so
    # anything over 20 MB is exceptional.
    TOO_LARGE_FILE_SIZE_LIMIT = 20 * 1024 * 1024

    too_large_files = []
    for f in input_api.AffectedFiles():
        # Check both added and modified files (but not deleted files).
        if f.Action() in ('A', 'M'):
            size = input_api.os_path.getsize(f.AbsoluteLocalPath())
            if size > TOO_LARGE_FILE_SIZE_LIMIT:
                too_large_files.append('%s: %d bytes' % (f.LocalPath(), size))

    if too_large_files:
        message = (
            'Do not commit large files to git since git scales badly for those.\n'
            +
            'Instead put the large files in cloud storage and use DEPS to\n' +
            'fetch them.\n' + '\n'.join(too_large_files))
        return [
            output_api.PresubmitError('Too large files found in commit',
                                      long_text=message + '\n')
        ]
    else:
        return []


def CheckFuzzTargetsOnUpload(input_api, output_api):
    """Checks specific for fuzz target sources."""
    EXPORTED_SYMBOLS = [
        'LLVMFuzzerInitialize',
        'LLVMFuzzerCustomMutator',
        'LLVMFuzzerCustomCrossOver',
        'LLVMFuzzerMutate',
    ]

    REQUIRED_HEADER = '#include "testing/libfuzzer/libfuzzer_exports.h"'

    def FilterFile(affected_file):
        """Ignore libFuzzer source code."""
        files_to_check = r'.*fuzz.*\.(h|hpp|hcc|cc|cpp|cxx)$'
        files_to_skip = r'^third_party/libFuzzer'

        return input_api.FilterSourceFile(affected_file,
                                          files_to_check=[files_to_check],
                                          files_to_skip=[files_to_skip])

    files_with_missing_header = []
    for f in input_api.AffectedSourceFiles(FilterFile):
        contents = input_api.ReadFile(f, 'r')
        if REQUIRED_HEADER in contents:
            continue

        if any(symbol in contents for symbol in EXPORTED_SYMBOLS):
            files_with_missing_header.append(f.LocalPath())

    if not files_with_missing_header:
        return []

    long_text = (
        'If you define any of the libFuzzer optional functions (%s), it is '
        'recommended to add \'%s\' directive. Otherwise, the fuzz target may '
        'work incorrectly on Mac (crbug.com/687076).\nNote that '
        'LLVMFuzzerInitialize should not be used, unless your fuzz target needs '
        'to access command line arguments passed to the fuzzer. Instead, prefer '
        'static initialization and shared resources as documented in '
        'https://chromium.googlesource.com/chromium/src/+/main/testing/'
        'libfuzzer/efficient_fuzzing.md#simplifying-initialization_cleanup.\n'
        % (', '.join(EXPORTED_SYMBOLS), REQUIRED_HEADER))

    return [
        output_api.PresubmitPromptWarning(message="Missing '%s' in:" %
                                          REQUIRED_HEADER,
                                          items=files_with_missing_header,
                                          long_text=long_text)
    ]


def _CheckNewImagesWarning(input_api, output_api):
    """
    Warns authors who add images into the repo to make sure their images are
    optimized before committing.
    """
    images_added = False
    image_paths = []
    errors = []
    filter_lambda = lambda x: input_api.FilterSourceFile(
        x,
        files_to_skip=(
            ('(?i).*test', r'.*\/junit\/') + input_api.DEFAULT_FILES_TO_SKIP),
        files_to_check=[r'.*\/(drawable|mipmap)'])
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=filter_lambda):
        local_path = f.LocalPath().lower()
        if any(
                local_path.endswith(extension)
                for extension in _IMAGE_EXTENSIONS):
            images_added = True
            image_paths.append(f)
    if images_added:
        errors.append(
            output_api.PresubmitPromptWarning(
                'It looks like you are trying to commit some images. If these are '
                'non-test-only images, please make sure to read and apply the tips in '
                'https://chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/'
                'binary_size/optimization_advice.md#optimizing-images\nThis check is '
                'FYI only and will not block your CL on the CQ.', image_paths))
    return errors


def ChecksAndroidSpecificOnUpload(input_api, output_api):
    """Groups upload checks that target android code."""
    results = []
    results.extend(_CheckAndroidCrLogUsage(input_api, output_api))
    results.extend(_CheckAndroidDebuggableBuild(input_api, output_api))
    results.extend(_CheckAndroidNewMdpiAssetLocation(input_api, output_api))
    results.extend(_CheckAndroidToastUsage(input_api, output_api))
    results.extend(_CheckAndroidTestAnnotationUsage(input_api, output_api))
    results.extend(_CheckAndroidWebkitImports(input_api, output_api))
    results.extend(_CheckAndroidXmlStyle(input_api, output_api, True))
    results.extend(_CheckNewImagesWarning(input_api, output_api))
    results.extend(_CheckAndroidInfoBarDeprecation(input_api, output_api))
    results.extend(_CheckAndroidNullAwayAnnotatedClasses(
        input_api, output_api))
    return results


def ChecksAndroidSpecificOnCommit(input_api, output_api):
    """Groups commit checks that target android code."""
    results = []
    results.extend(_CheckAndroidXmlStyle(input_api, output_api, False))
    results.extend(_CheckAndroidNullAwayAnnotatedClasses(
        input_api, output_api))
    return results


# TODO(chrishall): could we additionally match on any path owned by
#                  ui/accessibility/OWNERS ?
_ACCESSIBILITY_PATHS = (
    r'^chrome/browser.*/accessibility/',
    r'^chrome/browser/extensions/api/automation.*/',
    r'^chrome/renderer/extensions/accessibility_.*',
    r'^chrome/tests/data/accessibility/',
    r'^content/browser/accessibility/',
    r'^content/renderer/accessibility/',
    r'^content/tests/data/accessibility/',
    r'^extensions/renderer/api/automation/',
    r'^services/accessibility/',
    r'^services/screen_ai/',
    r'^ui/accessibility/',
    r'^ui/views/accessibility/',
)


def CheckAccessibilityRelnotesField(input_api, output_api):
    """Checks that commits to accessibility code contain an AX-Relnotes field in
    their commit message."""

    def FileFilter(affected_file):
        paths = _ACCESSIBILITY_PATHS
        return input_api.FilterSourceFile(affected_file, files_to_check=paths)

    # Only consider changes affecting accessibility paths.
    if not any(input_api.AffectedFiles(file_filter=FileFilter)):
        return []

    # AX-Relnotes can appear in either the description or the footer.
    # When searching the description, require 'AX-Relnotes:' to appear at the
    # beginning of a line.
    ax_regex = input_api.re.compile('ax-relnotes[:=]')
    description_has_relnotes = any(
        ax_regex.match(line)
        for line in input_api.change.DescriptionText().lower().splitlines())

    footer_relnotes = input_api.change.GitFootersFromDescription().get(
        'AX-Relnotes', [])
    if description_has_relnotes or footer_relnotes:
        return []

    # TODO(chrishall): link to Relnotes documentation in message.
    message = (
        "Missing 'AX-Relnotes:' field required for accessibility changes"
        "\n  please add 'AX-Relnotes: [release notes].' to describe any "
        "user-facing changes"
        "\n  otherwise add 'AX-Relnotes: n/a.' if this change has no "
        "user-facing effects"
        "\n  if this is confusing or annoying then please contact members "
        "of ui/accessibility/OWNERS.")

    return [output_api.PresubmitNotifyResult(message)]


_ACCESSIBILITY_ARIA_METHOD_CANDIDATES_PATTERNS = r'(\-\>|\.)(get|has|FastGet|FastHas)Attribute\('

_ACCESSIBILITY_ARIA_BAD_PARAMS_PATTERNS = (r'\(html_names::kAria(.*)Attr\)',
                                           r'\(html_names::kRoleAttr\)')

_ACCESSIBILITY_ARIA_FILE_CANDIDATES_PATTERNS = (r'.*/accessibility/.*.(cc|h)',
                                                r'.*/ax_.*.(cc|h)')


def CheckAccessibilityAriaElementAttributeGetters(input_api, output_api):
    """Checks that the blink accessibility code follows the defined patterns
    for checking aria attributes, so that ElementInternals is not bypassed."""

    # Limit to accessibility-related files.
    def FileFilter(affected_file):
        paths = _ACCESSIBILITY_ARIA_FILE_CANDIDATES_PATTERNS
        return input_api.FilterSourceFile(affected_file, files_to_check=paths)

    aria_method_regex = input_api.re.compile(
        _ACCESSIBILITY_ARIA_METHOD_CANDIDATES_PATTERNS)
    aria_bad_params_regex = input_api.re.compile(
        '|'.join(_ACCESSIBILITY_ARIA_BAD_PARAMS_PATTERNS))
    problems = []

    for f in input_api.AffectedSourceFiles(FileFilter):
        for line_num, line in f.ChangedContents():
            if aria_method_regex.search(line) and aria_bad_params_regex.search(
                    line):
                problems.append(
                    f'{f.LocalPath()}:{line_num}\n    {line.strip()}')

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Accessibility code should not use element methods to get or check'
                '\nthe presence of aria attributes'
                '\nPlease use ARIA-specific attribute access, e.g. HasAriaAttribute(),'
                '\nAriaTokenAttribute(), AriaBoolAttribute(), AriaBooleanAttribute(),'
                '\nAriaFloatAttribute().',
                problems,
            )
        ]
    return []


# string pattern, sequence of strings to show when pattern matches,
# error flag. True if match is a presubmit error, otherwise it's a warning.
_NON_INCLUSIVE_TERMS = (
    (
        # Note that \b pattern in python re is pretty particular. In this
        # regexp, 'class WhiteList ...' will match, but 'class FooWhiteList
        # ...' will not. This may require some tweaking to catch these cases
        # without triggering a lot of false positives. Leaving it naive and
        # less matchy for now.
        r'/(?i)\b((black|white)list|master|slave)\b',  # nocheck
        (
            'Please don\'t use blacklist, whitelist, '  # nocheck
            'or slave in your',  # nocheck
            'code and make every effort to use other terms. Using "// nocheck"',
            '"# nocheck" or "<!-- nocheck -->"',
            'at the end of the offending line will bypass this PRESUBMIT error',
            'but avoid using this whenever possible. Reach out to',
            'community@chromium.org if you have questions'),
        True), )


def ChecksCommon(input_api, output_api):
    """Checks common to both upload and commit."""
    results = []
    results.extend(
        input_api.canned_checks.PanProjectChecks(
            input_api, output_api, excluded_paths=_EXCLUDED_PATHS))

    author = input_api.change.author_email
    if author and author not in _KNOWN_ROBOTS:
        results.extend(
            input_api.canned_checks.CheckAuthorizedAuthor(
                input_api, output_api))

    results.extend(
        input_api.canned_checks.CheckChangeHasNoTabs(
            input_api,
            output_api,
            source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
    results.extend(
        input_api.RunTests(
            input_api.canned_checks.CheckVPythonSpec(input_api, output_api)))

    dirmd = 'dirmd.bat' if input_api.is_windows else 'dirmd'
    dirmd_bin = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                       'third_party', 'depot_tools', dirmd)
    results.extend(
        input_api.RunTests(
            input_api.canned_checks.CheckDirMetadataFormat(
                input_api, output_api, dirmd_bin)))
    results.extend(
        input_api.canned_checks.CheckOwnersDirMetadataExclusive(
            input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckNoNewMetadataInOwners(
            input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckInclusiveLanguage(
            input_api,
            output_api,
            excluded_directories_relative_path=[
                'infra', 'inclusive_language_presubmit_exempt_dirs.txt'
            ],
            non_inclusive_terms=_NON_INCLUSIVE_TERMS))
    results.extend(
        input_api.canned_checks.CheckNewDEPSHooksHasRequiredReviewers(
            input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckValidHostsInDEPSOnUpload(
            input_api, output_api))

    presubmit_py_filter = lambda f: input_api.FilterSourceFile(
        f, files_to_check=[r'.*PRESUBMIT(?:_test)?\.py$'])
    potential_paths = set(
        map(
            lambda f: input_api.os_path.dirname(f.AbsoluteLocalPath()),
            input_api.AffectedFiles(include_deletes=False,
                                    file_filter=presubmit_py_filter)))
    for full_path in potential_paths:
        test_file = input_api.os_path.join(full_path, 'PRESUBMIT_test.py')
        # The PRESUBMIT.py file (and the directory containing it) might have
        # been affected by being moved or removed, so only try to run the tests
        # if they still exist.
        if not input_api.os_path.exists(test_file):
            continue

        results.extend(
            input_api.canned_checks.RunUnitTestsInDirectory(
                input_api,
                output_api,
                full_path,
                files_to_check=[r'^PRESUBMIT_test\.py$']))
    return results


def CheckPatchFiles(input_api, output_api):
    problems = [
        f.LocalPath() for f in input_api.AffectedFiles()
        if f.LocalPath().endswith(('.orig', '.rej'))
    ]
    # Cargo.toml.orig files are part of third-party crates downloaded from
    # crates.io and should be included.
    problems = [f for f in problems if not f.endswith('Cargo.toml.orig')]
    if problems:
        return [
            output_api.PresubmitError("Don't commit .rej and .orig files.",
                                      problems)
        ]
    else:
        return []


def CheckBuildConfigMacrosWithoutInclude(input_api, output_api):
    # Excludes OS_CHROMEOS, which is not defined in build_config.h.
    macro_re = input_api.re.compile(
        r'^\s*#(el)?if.*\bdefined\(((COMPILER_|ARCH_CPU_|WCHAR_T_IS_)[^)]*)')
    include_re = input_api.re.compile(r'^#include\s+"build/build_config.h"',
                                      input_api.re.MULTILINE)
    extension_re = input_api.re.compile(r'\.[a-z]+$')
    errors = []
    config_h_file = input_api.os_path.join('build', 'build_config.h')
    for f in input_api.AffectedFiles(include_deletes=False):
        # The build-config macros are allowed to be used in build_config.h
        # without including itself.
        if f.LocalPath() == config_h_file:
            continue
        if not f.LocalPath().endswith(
            ('.h', '.c', '.cc', '.cpp', '.m', '.mm')):
            continue

        found_line_number = None
        found_macro = None
        all_lines = input_api.ReadFile(f, 'r').splitlines()
        for line_num, line in enumerate(all_lines):
            match = macro_re.search(line)
            if match:
                found_line_number = line_num
                found_macro = match.group(2)
                break
        if not found_line_number:
            continue

        found_include_line = -1
        for line_num, line in enumerate(all_lines):
            if include_re.search(line):
                found_include_line = line_num
                break
        if found_include_line >= 0 and found_include_line < found_line_number:
            continue

        if not f.LocalPath().endswith('.h'):
            primary_header_path = extension_re.sub('.h', f.AbsoluteLocalPath())
            try:
                content = input_api.ReadFile(primary_header_path, 'r')
                if include_re.search(content):
                    continue
            except IOError:
                pass
        errors.append('%s:%d %s macro is used without first including build/'
                      'build_config.h.' %
                      (f.LocalPath(), found_line_number, found_macro))
    if errors:
        return [output_api.PresubmitPromptWarning('\n'.join(errors))]
    return []


def CheckForSuperfluousStlIncludesInHeaders(input_api, output_api):
    stl_include_re = input_api.re.compile(r'^#include\s+<('
                                          r'algorithm|'
                                          r'array|'
                                          r'limits|'
                                          r'list|'
                                          r'map|'
                                          r'memory|'
                                          r'queue|'
                                          r'set|'
                                          r'string|'
                                          r'unordered_map|'
                                          r'unordered_set|'
                                          r'utility|'
                                          r'vector)>')
    std_namespace_re = input_api.re.compile(r'std::')
    errors = []
    for f in input_api.AffectedFiles():
        if not _IsCPlusPlusHeaderFile(input_api, f.LocalPath()):
            continue

        uses_std_namespace = False
        has_stl_include = False
        for line in f.NewContents():
            if has_stl_include and uses_std_namespace:
                break

            if not has_stl_include and stl_include_re.search(line):
                has_stl_include = True
                continue

            if not uses_std_namespace and (std_namespace_re.search(line)
                                           or 'no-std-usage-because-pch-file'
                                           in line):
                uses_std_namespace = True
                continue

        if has_stl_include and not uses_std_namespace:
            errors.append(
                '%s: Includes STL header(s) but does not reference std::' %
                f.LocalPath())
    if errors:
        return [output_api.PresubmitPromptWarning('\n'.join(errors))]
    return []


def _CheckForDeprecatedOSMacrosInFile(input_api, f):
    """Check for sensible looking, totally invalid OS macros."""
    preprocessor_statement = input_api.re.compile(r'^\s*#')
    os_macro = input_api.re.compile(r'defined\(OS_([^)]+)\)')
    results = []
    for lnum, line in f.ChangedContents():
        if preprocessor_statement.search(line):
            for match in os_macro.finditer(line):
                results.append(
                    '  %s:%d: %s' %
                    (f.LocalPath(), lnum, 'defined(OS_' + match.group(1) +
                     ') -> BUILDFLAG(IS_' + match.group(1) + ')'))
    return results


def CheckForDeprecatedOSMacros(input_api, output_api):
    """Check all affected files for invalid OS macros."""
    bad_macros = []
    # The OS_ macros are allowed to be used in build/build_config.h.
    config_h_file = input_api.os_path.join('build', 'build_config.h')
    for f in input_api.AffectedSourceFiles(None):
        if (not f.LocalPath().endswith(('.py', '.js', '.html', '.css', '.md'))
                and f.LocalPath() != config_h_file):
            bad_macros.extend(_CheckForDeprecatedOSMacrosInFile(input_api, f))

    if not bad_macros:
        return []

    return [
        output_api.PresubmitError(
            'OS macros have been deprecated. Please use BUILDFLAGs instead (still '
            'defined in build_config.h):', bad_macros)
    ]


def _CheckForInvalidIfDefinedMacrosInFile(input_api, f):
    """Check all affected files for invalid "if defined" macros."""
    ALWAYS_DEFINED_MACROS = (
        'TARGET_CPU_PPC',
        'TARGET_CPU_PPC64',
        'TARGET_CPU_68K',
        'TARGET_CPU_X86',
        'TARGET_CPU_ARM',
        'TARGET_CPU_MIPS',
        'TARGET_CPU_SPARC',
        'TARGET_CPU_ALPHA',
        'TARGET_IPHONE_SIMULATOR',
        'TARGET_OS_EMBEDDED',
        'TARGET_OS_IPHONE',
        'TARGET_OS_MAC',
        'TARGET_OS_UNIX',
        'TARGET_OS_WIN32',
    )
    ifdef_macro = input_api.re.compile(
        r'^\s*#.*(?:ifdef\s|defined\()([^\s\)]+)')
    results = []
    for lnum, line in f.ChangedContents():
        for match in ifdef_macro.finditer(line):
            if match.group(1) in ALWAYS_DEFINED_MACROS:
                always_defined = ' %s is always defined. ' % match.group(1)
                did_you_mean = 'Did you mean \'#if %s\'?' % match.group(1)
                results.append(
                    '    %s:%d %s\n\t%s' %
                    (f.LocalPath(), lnum, always_defined, did_you_mean))
    return results


def CheckForInvalidIfDefinedMacros(input_api, output_api):
    """Check all affected files for invalid "if defined" macros."""
    SKIPPED_PATHS = [
        'base/allocator/partition_allocator/src/partition_alloc/build_config.h',
        'build/build_config.h',
        'third_party/abseil-cpp/',
        'third_party/sqlite/',
    ]

    def affected_files_filter(f):
        # Normalize the local path to Linux-style path separators so that the
        # path comparisons work on Windows as well.
        path = f.UnixLocalPath()

        for skipped_path in SKIPPED_PATHS:
            if path.startswith(skipped_path):
                return False

        return path.endswith(('.h', '.c', '.cc', '.m', '.mm'))

    bad_macros = []
    for f in input_api.AffectedSourceFiles(affected_files_filter):
        bad_macros.extend(_CheckForInvalidIfDefinedMacrosInFile(input_api, f))

    if not bad_macros:
        return []

    return [
        output_api.PresubmitError(
            'Found ifdef check on always-defined macro[s]. Please fix your code\n'
            'or check the list of ALWAYS_DEFINED_MACROS in src/PRESUBMIT.py.',
            bad_macros)
    ]


def CheckForIPCRules(input_api, output_api):
    """Check for same IPC rules described in
    http://www.chromium.org/Home/chromium-security/education/security-tips-for-ipc
    """
    base_pattern = r'IPC_ENUM_TRAITS\('
    inclusion_pattern = input_api.re.compile(r'(%s)' % base_pattern)
    comment_pattern = input_api.re.compile(r'//.*(%s)' % base_pattern)

    problems = []
    for f in input_api.AffectedSourceFiles(None):
        local_path = f.LocalPath()
        if not local_path.endswith('.h'):
            continue
        for line_number, line in f.ChangedContents():
            if inclusion_pattern.search(
                    line) and not comment_pattern.search(line):
                problems.append('%s:%d\n    %s' %
                                (local_path, line_number, line.strip()))

    if problems:
        return [
            output_api.PresubmitPromptWarning(_IPC_ENUM_TRAITS_DEPRECATED,
                                              problems)
        ]
    else:
        return []


def CheckForLongPathnames(input_api, output_api):
    """Check to make sure no files being submitted have long paths.
    This causes issues on Windows.
    """
    problems = []
    for f in input_api.AffectedTestableFiles():
        local_path = f.LocalPath()
        # Windows has a path limit of 260 characters. Limit path length to 200 so
        # that we have some extra for the prefix on dev machines and the bots.
        if (local_path.startswith('third_party/blink/web_tests/platform/')
                and not local_path.startswith(
                    'third_party/blink/web_tests/platform/win')):
            # Do not check length of the path for files not used by Windows
            continue
        if len(local_path) > 200:
            problems.append(local_path)

    if problems:
        return [output_api.PresubmitError(_LONG_PATH_ERROR, problems)]
    else:
        return []


def CheckForIncludeGuards(input_api, output_api):
    """Check that header files have proper guards against multiple inclusion.
    If a file should not have such guards (and it probably should) then it
    should include the string "no-include-guard-because-multiply-included" or
    "no-include-guard-because-pch-file".
    """

    def is_chromium_header_file(f):
        # We only check header files under the control of the Chromium
        # project. This excludes:
        # - third_party/*, except blink.
        # - base/allocator/partition_allocator/: PartitionAlloc is a standalone
        #   library used outside of Chrome. Includes are referenced from its
        #   own base directory. It has its own `CheckForIncludeGuards`
        #   PRESUBMIT.py check.
        # - *_message_generator.h: They use include guards in a special,
        #   non-typical way.
        file_with_path = input_api.os_path.normpath(f.LocalPath())
        return (file_with_path.endswith('.h')
                and not file_with_path.endswith('_message_generator.h')
                and not file_with_path.endswith('com_imported_mstscax.h')
                and not file_with_path.startswith(
                    input_api.os_path.join('base', 'allocator',
                                           'partition_allocator'))
                and (not file_with_path.startswith('third_party')
                     or file_with_path.startswith(
                         input_api.os_path.join('third_party', 'blink'))))

    def replace_special_with_underscore(string):
        return input_api.re.sub(r'[+\\/.-]', '_', string)

    errors = []

    for f in input_api.AffectedSourceFiles(is_chromium_header_file):
        guard_name = None
        guard_line_number = None
        seen_guard_end = False
        bypass_checks_at_end_of_file = False

        file_with_path = input_api.os_path.normpath(f.LocalPath())
        base_file_name = input_api.os_path.splitext(
            input_api.os_path.basename(file_with_path))[0]
        upper_base_file_name = base_file_name.upper()

        expected_guard = replace_special_with_underscore(
            file_with_path.upper() + '_')

        # For "path/elem/file_name.h" we should really only accept
        # PATH_ELEM_FILE_NAME_H_ per coding style.  Unfortunately there
        # are too many (1000+) files with slight deviations from the
        # coding style. The most important part is that the include guard
        # is there, and that it's unique, not the name so this check is
        # forgiving for existing files.
        #
        # As code becomes more uniform, this could be made stricter.

        guard_name_pattern_list = [
            # Anything with the right suffix (maybe with an extra _).
            r'\w+_H__?',

            # To cover include guards with old Blink style.
            r'\w+_h',

            # Anything including the uppercase name of the file.
            r'\w*' + input_api.re.escape(
                replace_special_with_underscore(upper_base_file_name)) +
            r'\w*',
        ]
        guard_name_pattern = '|'.join(guard_name_pattern_list)
        guard_pattern = input_api.re.compile(r'#ifndef\s+(' +
                                             guard_name_pattern + ')')

        for line_number, line in enumerate(f.NewContents()):
            if ('no-include-guard-because-multiply-included' in line
                    or 'no-include-guard-because-pch-file' in line):
                bypass_checks_at_end_of_file = True
                break

            if guard_name is None:
                match = guard_pattern.match(line)
                if match:
                    guard_name = match.group(1)
                    guard_line_number = line_number

                    # We allow existing files to use include guards whose names
                    # don't match the chromium style guide, but new files should
                    # get it right.
                    if guard_name != expected_guard:
                        if f.Action() == 'A':  # If file was just 'A'dded
                            errors.append(
                                output_api.PresubmitPromptWarning(
                                    'Header using the wrong include guard name %s'
                                    % guard_name, [
                                        '%s:%d' %
                                        (f.LocalPath(), line_number + 1)
                                    ], 'Expected: %r\nFound:    %r' %
                                    (expected_guard, guard_name)))
            else:
                # The line after #ifndef should have a #define of the same name.
                if line_number == guard_line_number + 1:
                    expected_line = '#define %s' % guard_name
                    if line != expected_line:
                        errors.append(
                            output_api.PresubmitPromptWarning(
                                'Missing "%s" for include guard' %
                                expected_line,
                                ['%s:%d' % (f.LocalPath(), line_number + 1)],
                                'Expected: %r\nGot: %r' %
                                (expected_line, line)))

                if not seen_guard_end and line == '#endif  // %s' % guard_name:
                    seen_guard_end = True
                elif seen_guard_end:
                    if line.strip():
                        errors.append(
                            output_api.PresubmitPromptWarning(
                                'Include guard %s not covering the whole file'
                                % (guard_name), [f.LocalPath()]))
                        break  # Nothing else to check and enough to warn once.

        if bypass_checks_at_end_of_file:
            continue

        if guard_name is None:
            errors.append(
                output_api.PresubmitPromptWarning(
                    'Missing include guard in %s\n'
                    'Recommended name: %s\n'
                    'This check can be disabled by having the string\n'
                    '"no-include-guard-because-multiply-included" or\n'
                    '"no-include-guard-because-pch-file" in the header.' %
                    (f.LocalPath(), expected_guard)))
        elif not seen_guard_end:
            errors.append(
                output_api.PresubmitPromptWarning(
                    'Incorrect or missing include guard #endif in %s\n'
                    'Recommended #endif comment: // %s' %
                    (f.LocalPath(), expected_guard)))

    return errors


def CheckForWindowsLineEndings(input_api, output_api):
    """Check source code and known ascii text files for Windows style line
    endings.
    """
    known_text_files = r'.*\.(txt|html|htm|py|gyp|gypi|gn|isolate|icon)$'

    _WEBUI_FILES_EXTENSIONS = r'\.(css|html|js|ts|svg)$'

    file_inclusion_pattern = (known_text_files,
                              r'.+%s' % _IMPLEMENTATION_EXTENSIONS,
                              r'.+%s' % _HEADER_EXTENSIONS,
                              r'.+%s' % _WEBUI_FILES_EXTENSIONS)

    # Exclude folder that contains .ts files that are actually binary video
    # format and not TypeScript.
    file_exclusion_pattern = (r'media/test/data/')

    problems = []
    source_file_filter = lambda f: input_api.FilterSourceFile(
        f,
        files_to_check=file_inclusion_pattern,
        files_to_skip=file_exclusion_pattern)
    for f in input_api.AffectedSourceFiles(source_file_filter):
        # Ignore test files that contain crlf intentionally.
        if f.LocalPath().endswith('crlf.txt'):
            continue
        include_file = False
        for line in input_api.ReadFile(f, 'r').splitlines(True):
            if line.endswith('\r\n'):
                include_file = True
        if include_file:
            problems.append(f.LocalPath())

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Are you sure that you want '
                'these files to contain Windows style line endings?\n' +
                '\n'.join(problems))
        ]

    return []


def CheckIconFilesForLicenseHeaders(input_api, output_api):
    """Check that .icon files (which are fragments of C++) have license headers.
    """

    icon_files = (r'.*\.icon$', )

    icons = lambda x: input_api.FilterSourceFile(x, files_to_check=icon_files)
    return input_api.canned_checks.CheckLicense(input_api,
                                                output_api,
                                                source_file_filter=icons)


def CheckForUseOfChromeAppsDeprecations(input_api, output_api):
    """Check source code for use of Chrome App technologies being
    deprecated.
    """

    def _CheckForDeprecatedTech(input_api,
                                detection_list,
                                files_to_check=None,
                                files_to_skip=None):

        if (files_to_check or files_to_skip):
            source_file_filter = lambda f: input_api.FilterSourceFile(
                f, files_to_check=files_to_check, files_to_skip=files_to_skip)
        else:
            source_file_filter = None

        problems = []

        for f in input_api.AffectedSourceFiles(source_file_filter):
            if f.Action() == 'D':
                continue
            for _, line in f.ChangedContents():
                if any(detect in line for detect in detection_list):
                    problems.append(f.LocalPath())

        return problems

    problems = []

    # NMF: any files with extensions .nmf or NMF
    _NMF_FILES = r'\.(nmf|NMF)$'
    problems += _CheckForDeprecatedTech(
        input_api,
        detection_list=[''],  # any change to the file will trigger warning
        files_to_check=[r'.+%s' % _NMF_FILES])

    # MANIFEST: any manifest.json that in its diff includes "app":
    _MANIFEST_FILES = r'(manifest\.json)$'
    problems += _CheckForDeprecatedTech(
        input_api,
        detection_list=['"app":'],
        files_to_check=[r'.*%s' % _MANIFEST_FILES])

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'You are adding/modifying code'
                'related to technologies which will soon be deprecated (Chrome Apps'
                '). See this blog post for more details:\n'
                'https://blog.chromium.org/2020/08/changes-to-chrome-app-support-timeline.html\n'
                'and this documentation for options to replace these technologies:\n'
                'https://developer.chrome.com/docs/apps/migration/\n' +
                '\n'.join(problems))
        ]

    return []


def CheckSyslogUseWarningOnUpload(input_api, output_api, src_file_filter=None):
    """Checks that all source files use SYSLOG properly."""
    syslog_files = []
    for f in input_api.AffectedSourceFiles(src_file_filter):
        for line_number, line in f.ChangedContents():
            if 'SYSLOG' in line:
                syslog_files.append(f.LocalPath() + ':' + str(line_number))

    if syslog_files:
        return [
            output_api.PresubmitPromptWarning(
                'Please make sure there are no privacy sensitive bits of data in SYSLOG'
                ' calls.\nFiles to check:\n',
                items=syslog_files)
        ]
    return []


def CheckChangeOnUpload(input_api, output_api):
    if input_api.version < [2, 0, 0]:
        return [
            output_api.PresubmitError(
                'Your depot_tools is out of date. '
                'This PRESUBMIT.py requires at least presubmit_support version 2.0.0, '
                'but your version is %d.%d.%d' % tuple(input_api.version))
        ]
    results = []
    results.extend(
        input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
    return results


def CheckChangeOnCommit(input_api, output_api):
    if input_api.version < [2, 0, 0]:
        return [
            output_api.PresubmitError(
                'Your depot_tools is out of date. '
                'This PRESUBMIT.py requires at least presubmit_support version 2.0.0, '
                'but your version is %d.%d.%d' % tuple(input_api.version))
        ]

    results = []
    # Make sure the tree is 'open'.
    results.extend(
        input_api.canned_checks.CheckTreeIsOpen(
            input_api,
            output_api,
            json_url='http://chromium-status.appspot.com/current?format=json'))

    results.extend(
        input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckChangeHasBugField(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckChangeHasNoUnwantedTags(
            input_api, output_api))
    return results


def CheckStrings(input_api, output_api):
    """Check string ICU syntax validity and if translation screenshots exist."""
    # Skip translation screenshots check if a SkipTranslationScreenshotsCheck
    # footer is set to true.
    git_footers = input_api.change.GitFootersFromDescription()
    skip_screenshot_check_footer = [
        footer.lower() for footer in git_footers.get(
            u'Skip-Translation-Screenshots-Check', [])
    ]
    run_screenshot_check = u'true' not in skip_screenshot_check_footer

    import io
    import re
    import sys

    new_or_added_paths = set(f.LocalPath() for f in input_api.AffectedFiles()
                             if (f.Action() == 'A' or f.Action() == 'M'))
    removed_paths = set(f.LocalPath()
                        for f in input_api.AffectedFiles(include_deletes=True)
                        if f.Action() == 'D')

    affected_grds = [
        f for f in input_api.AffectedFiles()
        if f.LocalPath().endswith(('.grd', '.grdp'))
    ]
    affected_grds = [
        f for f in affected_grds if not 'testdata' in f.LocalPath()
    ]
    if not affected_grds:
        return []

    affected_png_paths = [
        f.LocalPath() for f in input_api.AffectedFiles()
        if f.LocalPath().endswith('.png')
    ]

    # Check for screenshots. Developers can upload screenshots using
    # tools/translation/upload_screenshots.py which finds and uploads
    # images associated with .grd files (e.g. test_grd/IDS_STRING.png for the
    # message named IDS_STRING in test.grd) and produces a .sha1 file (e.g.
    # test_grd/IDS_STRING.png.sha1) for each png when the upload is successful.
    #
    # The logic here is as follows:
    #
    # - If the CL has a .png file under the screenshots directory for a grd
    #   file, warn the developer. Actual images should never be checked into the
    #   Chrome repo.
    #
    # - If the CL contains modified or new messages in grd files and doesn't
    #   contain the corresponding .sha1 files, warn the developer to add images
    #   and upload them via tools/translation/upload_screenshots.py.
    #
    # - If the CL contains modified or new messages in grd files and the
    #   corresponding .sha1 files, everything looks good.
    #
    # - If the CL contains removed messages in grd files but the corresponding
    #   .sha1 files aren't removed, warn the developer to remove them.
    unnecessary_screenshots = []
    invalid_sha1 = []
    missing_sha1 = []
    missing_sha1_modified = []
    unnecessary_sha1_files = []

    # This checks verifies that the ICU syntax of messages this CL touched is
    # valid, and reports any found syntax errors.
    # Without this presubmit check, ICU syntax errors in Chromium strings can land
    # without developers being aware of them. Later on, such ICU syntax errors
    # break message extraction for translation, hence would block Chromium
    # translations until they are fixed.
    icu_syntax_errors = []
    sha1_pattern = input_api.re.compile(r'^[a-fA-F0-9]{40}$',
                                        input_api.re.MULTILINE)

    def _CheckScreenshotAdded(screenshots_dir, message_id):
        sha1_path = input_api.os_path.join(screenshots_dir,
                                           message_id + '.png.sha1')
        if sha1_path not in new_or_added_paths:
            missing_sha1.append(sha1_path)
        elif not _CheckValidSha1(sha1_path):
            invalid_sha1.append(sha1_path)

    def _CheckScreenshotModified(screenshots_dir, message_id):
        sha1_path = input_api.os_path.join(screenshots_dir,
                                           message_id + '.png.sha1')
        if sha1_path not in new_or_added_paths:
            missing_sha1_modified.append(sha1_path)
        elif not _CheckValidSha1(sha1_path):
            invalid_sha1.append(sha1_path)

    def _CheckValidSha1(sha1_path):
        return sha1_pattern.search(
            next('\n'.join(f.NewContents()) for f in input_api.AffectedFiles()
                 if f.LocalPath() == sha1_path))

    def _CheckScreenshotRemoved(screenshots_dir, message_id):
        sha1_path = input_api.os_path.join(screenshots_dir,
                                           message_id + '.png.sha1')
        if input_api.os_path.exists(
                sha1_path) and sha1_path not in removed_paths:
            unnecessary_sha1_files.append(sha1_path)

    def _ValidateIcuSyntax(text, level, signatures):
        """Validates ICU syntax of a text string.

        Check if text looks similar to ICU and checks for ICU syntax correctness
        in this case. Reports various issues with ICU syntax and values of
        variants. Supports checking of nested messages. Accumulate information of
        each ICU messages found in the text for further checking.

        Args:
          text: a string to check.
          level: a number of current nesting level.
          signatures: an accumulator, a list of tuple of (level, variable,
            kind, variants).

        Returns:
          None if a string is not ICU or no issue detected.
          A tuple of (message, start index, end index) if an issue detected.
        """
        valid_types = {
            'plural': (frozenset([
                '=0', '=1', '=2', '=3', 'zero', 'one', 'two', 'few', 'many',
                'other'
            ]), frozenset(['=1', 'other'])),
            'selectordinal': (frozenset([
                '=0', '=1', '=2', '=3', 'zero', 'one', 'two', 'few', 'many',
                'other'
            ]), frozenset(['one', 'other'])),
            'select': (frozenset(), frozenset(['other'])),
        }

        # Check if the message looks like an attempt to use ICU
        # plural. If yes - check if its syntax strictly matches ICU format.
        like = re.match(r'^[^{]*\{[^{]*\b(plural|selectordinal|select)\b',
                        text)
        if not like:
            signatures.append((level, None, None, None))
            return

        # Check for valid prefix and suffix
        m = re.match(
            r'^([^{]*\{)([a-zA-Z0-9_]+),\s*'
            r'(plural|selectordinal|select),\s*'
            r'(?:offset:\d+)?\s*(.*)', text, re.DOTALL)
        if not m:
            return (('This message looks like an ICU plural, '
                     'but does not follow ICU syntax.'), like.start(),
                    like.end())
        starting, variable, kind, variant_pairs = m.groups()
        variants, depth, last_pos = _ParseIcuVariants(variant_pairs,
                                                      m.start(4))
        if depth:
            return ('Invalid ICU format. Unbalanced opening bracket', last_pos,
                    len(text))
        first = text[0]
        ending = text[last_pos:]
        if not starting:
            return ('Invalid ICU format. No initial opening bracket',
                    last_pos - 1, last_pos)
        if not ending or '}' not in ending:
            return ('Invalid ICU format. No final closing bracket',
                    last_pos - 1, last_pos)
        elif first != '{':
            return ((
                'Invalid ICU format. Extra characters at the start of a complex '
                'message (go/icu-message-migration): "%s"') % starting, 0,
                    len(starting))
        elif ending != '}':
            return ((
                'Invalid ICU format. Extra characters at the end of a complex '
                'message (go/icu-message-migration): "%s"') % ending,
                    last_pos - 1, len(text) - 1)
        if kind not in valid_types:
            return (('Unknown ICU message type %s. '
                     'Valid types are: plural, select, selectordinal') % kind,
                    0, 0)
        known, required = valid_types[kind]
        defined_variants = set()
        for variant, variant_range, value, value_range in variants:
            start, end = variant_range
            if variant in defined_variants:
                return ('Variant "%s" is defined more than once' % variant,
                        start, end)
            elif known and variant not in known:
                return ('Variant "%s" is not valid for %s message' %
                        (variant, kind), start, end)
            defined_variants.add(variant)
            # Check for nested structure
            res = _ValidateIcuSyntax(value[1:-1], level + 1, signatures)
            if res:
                return (res[0], res[1] + value_range[0] + 1,
                        res[2] + value_range[0] + 1)
        missing = required - defined_variants
        if missing:
            return ('Required variants missing: %s' % ', '.join(missing), 0,
                    len(text))
        signatures.append((level, variable, kind, defined_variants))

    def _ParseIcuVariants(text, offset=0):
        """Parse variants part of ICU complex message.

        Builds a tuple of variant names and values, as well as
        their offsets in the input string.

        Args:
          text: a string to parse
          offset: additional offset to add to positions in the text to get correct
            position in the complete ICU string.

        Returns:
          List of tuples, each tuple consist of four fields: variant name,
          variant name span (tuple of two integers), variant value, value
          span (tuple of two integers).
        """
        depth, start, end = 0, -1, -1
        variants = []
        key = None
        span = None
        for idx, char in enumerate(text):
            if char == '{':
                if not depth:
                    start = idx
                    chunk = text[end + 1:start]
                    key = chunk.strip()
                    pos = offset + end + 1 + chunk.find(key)
                    span = (pos, pos + len(key))
                depth += 1
            elif char == '}':
                if not depth:
                    return variants, depth, offset + idx
                depth -= 1
                if not depth:
                    end = idx
                    variants.append((key, span, text[start:end + 1],
                                     (offset + start, offset + end + 1)))
        return variants, depth, offset + end + 1

    old_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                                   'translation')
        ]
        from helper import grd_helper
    finally:
        sys.path = old_sys_path

    for f in affected_grds:
        file_path = f.LocalPath()
        old_id_to_msg_map = {}
        new_id_to_msg_map = {}
        # Note that this code doesn't check if the file has been deleted. This is
        # OK because it only uses the old and new file contents and doesn't load
        # the file via its path.
        # It's also possible that a file's content refers to a renamed or deleted
        # file via a <part> tag, such as <part file="now-deleted-file.grdp">. This
        # is OK as well, because grd_helper ignores <part> tags when loading .grd or
        # .grdp files.
        if file_path.endswith('.grdp'):
            if f.OldContents():
                old_id_to_msg_map = grd_helper.GetGrdpMessagesFromString(
                    '\n'.join(f.OldContents()))
            if f.NewContents():
                new_id_to_msg_map = grd_helper.GetGrdpMessagesFromString(
                    '\n'.join(f.NewContents()))
        else:
            file_dir = input_api.os_path.dirname(file_path) or '.'
            if f.OldContents():
                old_id_to_msg_map = grd_helper.GetGrdMessages(
                    io.StringIO('\n'.join(f.OldContents())), file_dir)
            if f.NewContents():
                new_id_to_msg_map = grd_helper.GetGrdMessages(
                    io.StringIO('\n'.join(f.NewContents())), file_dir)

        grd_name, ext = input_api.os_path.splitext(
            input_api.os_path.basename(file_path))
        screenshots_dir = input_api.os_path.join(
            input_api.os_path.dirname(file_path),
            grd_name + ext.replace('.', '_'))

        # Compute added, removed and modified message IDs.
        old_ids = set(old_id_to_msg_map)
        new_ids = set(new_id_to_msg_map)
        added_ids = new_ids - old_ids
        removed_ids = old_ids - new_ids
        modified_ids = set([])
        for key in old_ids.intersection(new_ids):
            if (old_id_to_msg_map[key].ContentsAsXml('', True)
                    != new_id_to_msg_map[key].ContentsAsXml('', True)):
                # The message content itself changed. Require an updated screenshot.
                modified_ids.add(key)
            elif (old_id_to_msg_map[key].attrs['meaning']
                  != new_id_to_msg_map[key].attrs['meaning']):
                # The message meaning changed. We later check for a screenshot.
                modified_ids.add(key)

        if run_screenshot_check:
            # Check the screenshot directory for .png files. Warn if there is any.
            for png_path in affected_png_paths:
                if png_path.startswith(screenshots_dir):
                    unnecessary_screenshots.append(png_path)

            for added_id in added_ids:
                _CheckScreenshotAdded(screenshots_dir, added_id)

            for modified_id in modified_ids:
                _CheckScreenshotModified(screenshots_dir, modified_id)

            for removed_id in removed_ids:
                _CheckScreenshotRemoved(screenshots_dir, removed_id)

        # Check new and changed strings for ICU syntax errors.
        for key in added_ids.union(modified_ids):
            msg = new_id_to_msg_map[key].ContentsAsXml('', True)
            err = _ValidateIcuSyntax(msg, 0, [])
            if err is not None:
                icu_syntax_errors.append(str(key) + ': ' + str(err[0]))

    results = []
    if run_screenshot_check:
        if unnecessary_screenshots:
            results.append(
                output_api.PresubmitError(
                    'Do not include actual screenshots in the changelist. Run '
                    'tools/translation/upload_screenshots.py to upload them instead:',
                    sorted(unnecessary_screenshots)))

        if missing_sha1:
            results.append(
                output_api.PresubmitError(
                    'You are adding UI strings.\n'
                    'To ensure the best translations, take screenshots of the relevant UI '
                    '(https://g.co/chrome/translation) and add these files to your '
                    'changelist:', sorted(missing_sha1)))

        if invalid_sha1:
            results.append(
                output_api.PresubmitError(
                    'The following files do not seem to contain valid sha1 hashes. '
                    'Make sure they contain hashes created by '
                    'tools/translation/upload_screenshots.py:',
                    sorted(invalid_sha1)))

        if missing_sha1_modified:
            results.append(
                output_api.PresubmitError(
                    'You are modifying UI strings or their meanings.\n'
                    'To ensure the best translations, take screenshots of the relevant UI '
                    '(https://g.co/chrome/translation) and add these files to your '
                    'changelist:', sorted(missing_sha1_modified)))

        if unnecessary_sha1_files:
            results.append(
                output_api.PresubmitError(
                    'You removed strings associated with these files. Remove:',
                    sorted(unnecessary_sha1_files)))
    else:
        results.append(
            output_api.PresubmitPromptOrNotify('Skipping translation '
                                               'screenshots check.'))

    if icu_syntax_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                'ICU syntax errors were found in the following strings (problems or '
                'feedback? Contact rainhard@chromium.org):',
                items=icu_syntax_errors))

    return results


def CheckTranslationExpectations(input_api,
                                 output_api,
                                 repo_root=None,
                                 translation_expectations_path=None,
                                 grd_files=None):
    import sys
    affected_grds = [
        f for f in input_api.AffectedFiles()
        if (f.LocalPath().endswith('.grd') or f.LocalPath().endswith('.grdp'))
    ]
    if not affected_grds:
        return []

    old_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(), 'tools',
                                   'translation')
        ]
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'third_party', 'depot_tools')
        ]
        from helper import git_helper
        from helper import translation_helper
        import gclient_utils
    finally:
        sys.path = old_sys_path

    # Check that translation expectations can be parsed and we can get a list of
    # translatable grd files. |repo_root| and |translation_expectations_path| are
    # only passed by tests.
    if not repo_root:
        repo_root = input_api.PresubmitLocalPath()
    if not translation_expectations_path:
        translation_expectations_path = input_api.os_path.join(
            repo_root, 'tools', 'gritsettings', 'translation_expectations.pyl')
    is_cog = gclient_utils.IsEnvCog()
    # Git is not available in cog workspaces.
    if not grd_files and not is_cog:
        grd_files = git_helper.list_grds_in_repository(repo_root)
    if not grd_files:
        grd_files = []

    # Ignore bogus grd files used only for testing
    # ui/webui/resources/tools/generate_grd.py.
    ignore_path = input_api.os_path.join('ui', 'webui', 'resources', 'tools',
                                         'tests')
    grd_files = [p for p in grd_files if ignore_path not in p]

    # Ensure no duplicate basenames.
    basename_to_src_paths = {}
    for grd_path in grd_files:
        basename = input_api.os_path.basename(grd_path)
        basename_to_src_paths.setdefault(basename, [])
        basename_to_src_paths[basename].append(grd_path)
    for src_paths in basename_to_src_paths.values():
        if len(src_paths) > 1:
            return [
                output_api.PresubmitNotifyResult(
                    'Multiple string files have the same basename. This will result in '
                    'missing translations. Files: %s' % ', '.join(src_paths))
            ]

    try:
        translation_helper.get_translatable_grds(
            repo_root, grd_files, translation_expectations_path, is_cog)
    except Exception as e:
        return [
            output_api.PresubmitNotifyResult(
                'Failed to get a list of translatable grd files. This happens when:\n'
                ' - One of the modified grd or grdp files cannot be parsed or\n'
                ' - %s is not updated.\n'
                'Stack:\n%s' % (translation_expectations_path, str(e)))
        ]
    return []


def CheckStableMojomChanges(input_api, output_api):
    """Changes to [Stable] mojom types must preserve backward-compatibility."""
    no_stable_mojom_checks = input_api.change.GitFootersFromDescription().get(
        'No-Stable-Mojom-Checks', None)

    expect_stable_mojom_failures = False
    if no_stable_mojom_checks:
        if no_stable_mojom_checks == ['true']:
            expect_stable_mojom_failures = True
        else:
            return [
                output_api.PresubmitError(
                    f'If present, No-Stable-Mojom-Checks only accepts the value '
                    f'"true", but got "{no_stable_mojom_checks}" instead.')
            ]

    def CheckMojomsIfNeeded():
        changed_mojoms = input_api.AffectedFiles(
            include_deletes=True,
            file_filter=lambda f: f.LocalPath().endswith(('.mojom')))

        if not changed_mojoms or input_api.no_diffs:
            return []

        delta = []
        for mojom in changed_mojoms:
            delta.append({
                'filename': mojom.LocalPath(),
                'old': '\n'.join(mojom.OldContents()) or None,
                'new': '\n'.join(mojom.NewContents()) or None,
            })

        process = input_api.subprocess.Popen([
            input_api.python3_executable,
            input_api.os_path.join(
                input_api.PresubmitLocalPath(), 'mojo', 'public', 'tools',
                'mojom', 'check_stable_mojom_compatibility.py'), '--src-root',
            input_api.PresubmitLocalPath()
        ],
                                             stdin=input_api.subprocess.PIPE,
                                             stdout=input_api.subprocess.PIPE,
                                             stderr=input_api.subprocess.PIPE,
                                             universal_newlines=True)
        (_, error) = process.communicate(input=input_api.json.dumps(delta))
        if process.returncode:
            return [
                output_api.PresubmitError(
                    'One or more [Stable] mojom definitions changed in a way '
                    'that breaks backward compatibility. See '
                    'https://chromium.googlesource.com/chromium/src/+/HEAD/mojo/public/tools/bindings/README.md#versioning'
                    ' for details.\n\n'
                    'If you are confident this is a false positive, add '
                    '`No-Stable-Mojom-Checks: true` to the git footers to suppress '
                    'this check.',
                    long_text=error)
            ]
        return []

    results = CheckMojomsIfNeeded()
    if bool(results) != expect_stable_mojom_failures:
        if expect_stable_mojom_failures:
            return [
                output_api.PresubmitError(
                    'No [Stable] mojom definitions changed in a way breaks '
                    'backward compatibility.\n\n'
                    'Please remove the unnecessary git footer '
                    '`No-Stable-Mojom-Checks: true`.')
            ]
        else:
            return results
    return []


def CheckDeprecationOfPreferences(input_api, output_api):
    """Removing a preference should come with a deprecation."""

    def FilterFile(affected_file):
        """Accept only .cc files and the like."""
        file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS]
        files_to_skip = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
                         input_api.DEFAULT_FILES_TO_SKIP)
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=file_inclusion_pattern,
            files_to_skip=files_to_skip)

    def ModifiedLines(affected_file):
        """Returns a list of tuples (line number, line text) of added and removed
        lines.

        Deleted lines share the same line number as the previous line.

        This relies on the scm diff output describing each changed code section
        with a line of the form

        ^@@ <old line num>,<old size> <new line num>,<new size> @@$
        """
        line_num = 0
        modified_lines = []
        for line in affected_file.GenerateScmDiff().splitlines():
            # Extract <new line num> of the patch fragment (see format above).
            m = input_api.re.match(r'^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@',
                                   line)
            if m:
                line_num = int(m.groups(1)[0])
                continue
            if ((line.startswith('+') and not line.startswith('++'))
                    or (line.startswith('-') and not line.startswith('--'))):
                modified_lines.append((line_num, line))

            if not line.startswith('-'):
                line_num += 1
        return modified_lines

    def FindLineWith(lines, needle):
        """Returns the line number (i.e. index + 1) in `lines` containing `needle`.

        If 0 or >1 lines contain `needle`, -1 is returned.
        """
        matching_line_numbers = [
            # + 1 for 1-based counting of line numbers.
            i + 1 for i, line in enumerate(lines) if needle in line
        ]
        return matching_line_numbers[0] if len(
            matching_line_numbers) == 1 else -1

    def ModifiedPrefMigration(affected_file):
        """Returns whether the MigrateObsolete.*Pref functions were modified."""
        # Determine first and last lines of MigrateObsolete.*Pref functions.
        new_contents = affected_file.NewContents()
        range_1 = (FindLineWith(new_contents,
                                'BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS'),
                   FindLineWith(new_contents,
                                'END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS'))
        range_2 = (FindLineWith(new_contents,
                                'BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS'),
                   FindLineWith(new_contents,
                                'END_MIGRATE_OBSOLETE_PROFILE_PREFS'))
        if (-1 in range_1 + range_2):
            raise Exception(
                'Broken .*MIGRATE_OBSOLETE_.*_PREFS markers in browser_prefs.cc.'
            )

        # Check whether any of the modified lines are part of the
        # MigrateObsolete.*Pref functions.
        for line_nr, _ in ModifiedLines(affected_file):
            if (range_1[0] <= line_nr <= range_1[1]
                    or range_2[0] <= line_nr <= range_2[1]):
                return True
        return False

    register_pref_pattern = input_api.re.compile(r'Register.+Pref')
    browser_prefs_file_pattern = input_api.re.compile(
        r'chrome/browser/prefs/browser_prefs.cc')

    changes = input_api.AffectedFiles(include_deletes=True,
                                      file_filter=FilterFile)
    potential_problems = []
    for f in changes:
        for line in f.GenerateScmDiff().splitlines():
            # Check deleted lines for pref registrations.
            if (line.startswith('-') and not line.startswith('--')
                    and register_pref_pattern.search(line)):
                potential_problems.append('%s: %s' % (f.LocalPath(), line))

        if browser_prefs_file_pattern.search(f.LocalPath()):
            # If the developer modified the MigrateObsolete.*Prefs() functions, we
            # assume that they knew that they have to deprecate preferences and don't
            # warn.
            try:
                if ModifiedPrefMigration(f):
                    return []
            except Exception as e:
                return [output_api.PresubmitError(str(e))]

    if potential_problems:
        return [
            output_api.PresubmitPromptWarning(
                'Discovered possible removal of preference registrations.\n\n'
                'Please make sure to properly deprecate preferences by clearing their\n'
                'value for a couple of milestones before finally removing the code.\n'
                'Otherwise data may stay in the preferences files forever. See\n'
                'Migrate*Prefs() in chrome/browser/prefs/browser_prefs.cc and\n'
                'chrome/browser/prefs/README.md for examples.\n'
                'This may be a false positive warning (e.g. if you move preference\n'
                'registrations to a different place or if the preference was only\n'
                'written to by the policy stack).\n', potential_problems)
        ]
    return []


def CheckConsistentGrdChanges(input_api, output_api):
    """Changes to GRD files must be consistent for tools to read them."""
    changed_grds = input_api.AffectedFiles(
        include_deletes=False,
        file_filter=lambda f: f.LocalPath().endswith(('.grd')))
    errors = []
    invalid_file_regexes = [(input_api.re.compile(matcher), msg)
                            for matcher, msg in _INVALID_GRD_FILE_LINE]
    for grd in changed_grds:
        for i, line in enumerate(grd.NewContents()):
            for matcher, msg in invalid_file_regexes:
                if matcher.search(line):
                    errors.append(
                        output_api.PresubmitError(
                            'Problem on {grd}:{i} - {msg}'.format(
                                grd=grd.LocalPath(), i=i + 1, msg=msg)))
    return errors


def CheckAssertAshOnlyCode(input_api, output_api):
    """Errors if a BUILD.gn file in an ash/ directory doesn't include
    assert(is_chromeos).
    For a transition period, assert(is_chromeos_ash) is also accepted.
    """

    def FileFilter(affected_file):
        """Includes directories known to be Ash only."""
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=(
                r'^ash/.*BUILD\.gn',  # Top-level src/ash/.
                r'.*/ash/.*BUILD\.gn'),  # Any path component.
            files_to_skip=(input_api.DEFAULT_FILES_TO_SKIP))

    errors = []
    pattern = input_api.re.compile(r'assert\(is_chromeos(_ash)?\b')
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=FileFilter):
        if (not pattern.search(input_api.ReadFile(f))):
            errors.append(
                output_api.PresubmitError(
                    'Please add assert(is_chromeos) to %s. If that\'s not '
                    'possible, please create an issue and add a comment such '
                    'as:\n  # TODO(crbug.com/XXX): add '
                    'assert(is_chromeos) when ...' % f.LocalPath()))
    return errors


def _IsMiraclePtrDisallowed(input_api, affected_file):
    path = affected_file.UnixLocalPath()
    if not _IsCPlusPlusFile(input_api, path):
        return False

    # Renderer-only code is generally allowed to use MiraclePtr. These
    # directories, however, are specifically disallowed, for perf reasons.
    if ('third_party/blink/renderer/core/' in path
            or 'third_party/blink/renderer/platform/heap/' in path
            or 'third_party/blink/renderer/platform/wtf/' in path
            or 'third_party/blink/renderer/platform/fonts/' in path):
        return True

    # We assume that everything else may be used outside of Renderer processes.
    return False


# TODO(crbug.com/40206238): Remove these checks, once they are replaced
# by the Chromium Clang Plugin (which will be preferable because it will
# 1) report errors earlier - at compile-time and 2) cover more rules).
def CheckRawPtrUsage(input_api, output_api):
    """Rough checks that raw_ptr<T> usage guidelines are followed."""
    errors = []
    # The regex below matches "raw_ptr<" following a word boundary, but not in a
    # C++ comment.
    raw_ptr_matcher = input_api.re.compile(r'^((?!//).)*\braw_ptr<')
    file_filter = lambda f: _IsMiraclePtrDisallowed(input_api, f)
    for f, line_num, line in input_api.RightHandSideLines(file_filter):
        if raw_ptr_matcher.search(line):
            errors.append(
                output_api.PresubmitError(
                    f'Problem on {f.LocalPath()}:{line_num} - '
                    'raw_ptr<T> should not be used in this renderer code '
                    '(as documented in the "Pointers to unprotected memory" '
                    'section in //base/memory/raw_ptr.md)'))
    return errors


def CheckAdvancedMemorySafetyChecksUsage(input_api, output_api):
    """Checks that ADVANCED_MEMORY_SAFETY_CHECKS() macro is neither added nor
    removed as it is managed by the memory safety team internally.
    Do not add / remove it manually."""
    paths = set([])
    # The regex below matches "ADVANCED_MEMORY_SAFETY_CHECKS(" following a word
    # boundary, but not in a C++ comment.
    macro_matcher = input_api.re.compile(
        r'^((?!//).)*\bADVANCED_MEMORY_SAFETY_CHECKS\(',
        input_api.re.MULTILINE)
    for f in input_api.AffectedFiles():
        if not _IsCPlusPlusFile(input_api, f.LocalPath()):
            continue
        if macro_matcher.search(f.GenerateScmDiff()):
            paths.add(f.LocalPath())
    if not paths:
        return []
    return [
        output_api.PresubmitPromptWarning(
            'ADVANCED_MEMORY_SAFETY_CHECKS() macro is managed by '
            'the memory safety team (chrome-memory-safety@). '
            'Please contact us to add/delete the uses of the macro.', paths)
    ]


def CheckPythonShebang(input_api, output_api):
    """Checks that python scripts use #!/usr/bin/env instead of hardcoding a
    system-wide python.
    """
    errors = []
    sources = lambda affected_file: input_api.FilterSourceFile(
        affected_file,
        files_to_skip=((_THIRD_PARTY_EXCEPT_BLINK,
                        r'third_party/blink/web_tests/external/') + input_api.
                       DEFAULT_FILES_TO_SKIP),
        files_to_check=[r'.*\.py$'])
    for f in input_api.AffectedSourceFiles(sources):
        for line_num, line in f.ChangedContents():
            if line_num == 1 and line.startswith('#!/usr/bin/python'):
                errors.append(f.LocalPath())
            break

    result = []
    for file in errors:
        result.append(
            output_api.PresubmitError(
                "Please use '#!/usr/bin/env python/2/3' as the shebang of %s" %
                file))
    return result


def CheckAndroidTestAnnotations(input_api, output_api):
    """Checks that tests have either @Batch or @DoNotBatch annotation. If this
    is not an instrumentation test, disregard."""

    batch_annotation = input_api.re.compile(r'^\s*@Batch')
    do_not_batch_annotation = input_api.re.compile(r'^\s*@DoNotBatch')
    robolectric_test = input_api.re.compile(
        r'@RunWith\((.*?)RobolectricTestRunner')
    test_class_declaration = input_api.re.compile(r'^\s*public\sclass.*Test')
    uiautomator_test = input_api.re.compile(r'[uU]i[aA]utomator')
    test_annotation_declaration = input_api.re.compile(
        r'^\s*public\s@interface\s.*{')

    missing_annotation_errors = []
    extra_annotation_errors = []
    wrong_robolectric_test_runner_errors = []

    def _FilterFile(affected_file):
        return input_api.FilterSourceFile(
            affected_file,
            files_to_skip=input_api.DEFAULT_FILES_TO_SKIP,
            files_to_check=[r'.*Test\.java$'])

    for f in input_api.AffectedSourceFiles(_FilterFile):
        batch_matched = None
        do_not_batch_matched = None
        is_instrumentation_test = True
        test_annotation_declaration_matched = None
        has_base_robolectric_rule = False
        for line in f.NewContents():
            if 'BaseRobolectricTestRule' in line:
                has_base_robolectric_rule = True
                continue
            if m := robolectric_test.search(line):
                is_instrumentation_test = False
                if not m.group(1) and not has_base_robolectric_rule:
                    path = str(f.LocalPath())
                    # These two spots cannot use it.
                    if 'webapk' not in path and 'build' not in path:
                        wrong_robolectric_test_runner_errors.append(path)
                break
            if uiautomator_test.search(line):
                is_instrumentation_test = False
                break
            if not batch_matched:
                batch_matched = batch_annotation.search(line)
            if not do_not_batch_matched:
                do_not_batch_matched = do_not_batch_annotation.search(line)
            test_class_declaration_matched = test_class_declaration.search(
                line)
            test_annotation_declaration_matched = test_annotation_declaration.search(
                line)
            if test_class_declaration_matched or test_annotation_declaration_matched:
                break
        if test_annotation_declaration_matched:
            continue
        if (is_instrumentation_test and not batch_matched
                and not do_not_batch_matched):
            missing_annotation_errors.append(str(f.LocalPath()))
        if (not is_instrumentation_test
                and (batch_matched or do_not_batch_matched)):
            extra_annotation_errors.append(str(f.LocalPath()))

    results = []

    if missing_annotation_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                """
A change was made to an on-device test that has neither been annotated with
@Batch nor @DoNotBatch. If this is a new test, please add the annotation. If
this is an existing test, please consider adding it if you are sufficiently
familiar with the test (but do so as a separate change).

See https://source.chromium.org/chromium/chromium/src/+/main:docs/testing/batching_instrumentation_tests.md
""", missing_annotation_errors))
    if extra_annotation_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                """
Robolectric tests do not need a @Batch or @DoNotBatch annotations.
""", extra_annotation_errors))
    if wrong_robolectric_test_runner_errors:
        results.append(
            output_api.PresubmitPromptWarning(
                """
Robolectric tests should use either @RunWith(BaseRobolectricTestRunner.class) (or
a subclass of it), or use "@Rule BaseRobolectricTestRule".
""", wrong_robolectric_test_runner_errors))

    return results


def _CheckAndroidNullAwayAnnotatedClasses(input_api, output_api):
    """Checks that Java classes/interfaces/annotations are null-annotated."""

    # clank repo is not null-marked
    if input_api.change.RepositoryRoot().endswith('clank'):
        return []

    nullmarked_annotation = input_api.re.compile(
        r'^\s*@(NullMarked|NullUnmarked)')

    missing_annotation_errors = []

    def _FilterFile(affected_file):
        return input_api.FilterSourceFile(
            affected_file,
            files_to_skip=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
                           input_api.DEFAULT_FILES_TO_SKIP + (
                               r'.*Test.*\.java',
                               r'^build/.*',
                               r'^chromecast/.*',
                               r'^components/cronet/.*',
                               r'^tools/.*',
                           )),
            files_to_check=[r'.*\.java$'])

    for f in input_api.AffectedSourceFiles(_FilterFile):
        if f.Action() != 'A':
            continue
        for line in f.NewContents():
            if nullmarked_annotation.search(line):
                break
        else:
            missing_annotation_errors.append(str(f.LocalPath()))

    results = []

    if missing_annotation_errors:
        results.append(
            output_api.PresubmitError(
                """
Please add @NullMarked and fix the NullAway warnings in the following files
(see https://chromium.googlesource.com/chromium/src/+/main/styleguide/java/nullaway.md):
""", missing_annotation_errors))

    return results


def CheckNoJsInIos(input_api, output_api):
    """Checks to make sure that JavaScript files are not used on iOS."""

    def _FilterFile(affected_file):
        return input_api.FilterSourceFile(
            affected_file,
            files_to_skip=input_api.DEFAULT_FILES_TO_SKIP +
            (r'^ios/third_party/*', r'^ios/tools/*', r'^third_party/*',
             r'^components/autofill/ios/form_util/resources/*'),
            files_to_check=[r'^ios/.*\.js$', r'.*/ios/.*\.js$'])

    deleted_files = []

    # Collect filenames of all removed JS files.
    for f in input_api.AffectedFiles(file_filter=_FilterFile):
        local_path = f.LocalPath()

        if input_api.os_path.splitext(
                local_path)[1] == '.js' and f.Action() == 'D':
            deleted_files.append(input_api.os_path.basename(local_path))

    error_paths = []
    moved_paths = []
    warning_paths = []

    for f in input_api.AffectedSourceFiles(_FilterFile):
        local_path = f.LocalPath()

        if input_api.os_path.splitext(local_path)[1] == '.js':
            if f.Action() == 'A':
                if input_api.os_path.basename(local_path) in deleted_files:
                    # This script was probably moved rather than newly created.
                    # Present a warning instead of an error for these cases.
                    moved_paths.append(local_path)
                else:
                    error_paths.append(local_path)
            elif f.Action() != 'D':
                warning_paths.append(local_path)

    results = []

    if warning_paths:
        results.append(
            output_api.PresubmitPromptWarning(
                'TypeScript is now fully supported for iOS feature scripts. '
                'Consider converting JavaScript files to TypeScript. See '
                '//ios/web/public/js_messaging/README.md for more details.',
                warning_paths))

    if moved_paths:
        results.append(
            output_api.PresubmitPromptWarning(
                'Do not use JavaScript on iOS for new files as TypeScript is '
                'fully supported. (If this is a moved file, you may leave the '
                'script unconverted.) See //ios/web/public/js_messaging/README.md '
                'for help using scripts on iOS.', moved_paths))

    if error_paths:
        results.append(
            output_api.PresubmitError(
                'Do not use JavaScript on iOS as TypeScript is fully supported. '
                'See //ios/web/public/js_messaging/README.md for help using '
                'scripts on iOS.', error_paths))

    return results


def CheckLibcxxRevisionsMatch(input_api, output_api):
    """Check to make sure the libc++ version matches across deps files."""
    # Disable check for changes to sub-repositories.
    if input_api.PresubmitLocalPath() != input_api.change.RepositoryRoot():
        return []

    DEPS_FILES = ['DEPS', 'buildtools/deps_revisions.gni']

    file_filter = lambda f: f.UnixLocalPath() in DEPS_FILES
    changed_deps_files = input_api.AffectedFiles(file_filter=file_filter)
    if not changed_deps_files:
        return []

    def LibcxxRevision(file):
        file = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                      *file.split('/'))
        return input_api.re.search(r'libcxx_revision.*[:=].*[\'"](\w+)[\'"]',
                                   input_api.ReadFile(file)).group(1)

    if len(set([LibcxxRevision(f) for f in DEPS_FILES])) == 1:
        return []

    return [
        output_api.PresubmitError(
            'libcxx_revision not equal across %s' % ', '.join(DEPS_FILES),
            changed_deps_files)
    ]


def CheckDanglingUntriaged(input_api, output_api):
    """Warn developers adding DanglingUntriaged raw_ptr."""

    # Ignore during git presubmit --all.
    #
    # This would be too costly, because this would check every lines of every
    # C++ files. Check from _BANNED_CPP_FUNCTIONS are also reading the whole
    # source code, but only once to apply every checks. It seems the bots like
    # `win-presubmit` are particularly sensitive to reading the files. Adding
    # this check caused the bot to run 2x longer. See https://crbug.com/1486612.
    if input_api.no_diffs:
        return []

    def FilterFile(file):
        return input_api.FilterSourceFile(
            file,
            files_to_check=[r'.*\.(h|cc|cpp|cxx|m|mm)$'],
            files_to_skip=[r'^base/allocator.*'],
        )

    count = 0
    for f in input_api.AffectedFiles(file_filter=FilterFile):
        count -= sum([l.count('DanglingUntriaged') for l in f.OldContents()])
        count += sum([l.count('DanglingUntriaged') for l in f.NewContents()])

    # Most likely, nothing changed:
    if count == 0:
        return []

    # Congrats developers for improving it:
    if count < 0:
        message = f'DanglingUntriaged pointers removed: {-count}\nThank you!'
        return [output_api.PresubmitNotifyResult(message)]

    # Check for 'DanglingUntriaged-notes' in the description:
    notes_regex = input_api.re.compile('DanglingUntriaged-notes[:=]')
    if any(
            notes_regex.match(line)
            for line in input_api.change.DescriptionText().splitlines()):
        return []

    # Check for DanglingUntriaged-notes in the git footer:
    if input_api.change.GitFootersFromDescription().get(
            'DanglingUntriaged-notes', []):
        return []

    message = ("""Unexpected new occurrences of `DanglingUntriaged` detected.
Please avoid adding new ones.

See documentation:
https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md

See also the guide to fix dangling pointers:
https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr_guide.md

To disable this warning, please add in the commit description:
DanglingUntriaged-notes: <rationale for new untriaged dangling pointers>""")

    return [output_api.PresubmitPromptWarning(message)]


def CheckInlineConstexprDefinitionsInHeaders(input_api, output_api):
    """Checks that non-static constexpr definitions in headers are inline."""
    # In a properly formatted file, constexpr definitions inside classes or
    # structs will have additional whitespace at the beginning of the line.
    # The pattern looks for variables initialized as constexpr kVar = ...; or
    # constexpr kVar{...};
    # The pattern does not match expressions that have braces in kVar to avoid
    # matching constexpr functions.
    pattern = input_api.re.compile(r'^constexpr (?!inline )[^\(\)]*[={]')
    attribute_pattern = input_api.re.compile(
        r'(\[\[[a-zA-Z_:]+\]\]|[A-Z]+[A-Z_]+) ')
    problems = []
    for f in input_api.AffectedFiles():
        if not _IsCPlusPlusHeaderFile(input_api, f.LocalPath()):
            continue

        for line_number, line in f.ChangedContents():
            line = attribute_pattern.sub('', line)
            if pattern.search(line):
                problems.append(f'{f.LocalPath()}: {line_number}\n    {line}')

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Consider inlining constexpr variable definitions in headers '
                'outside of classes to avoid unnecessary copies of the '
                'constant. See https://abseil.io/tips/168 for more details.',
                problems)
        ]
    else:
        return []


def CheckTodoBugReferences(input_api, output_api):
    """Checks that bugs in TODOs use updated issue tracker IDs."""

    files_to_skip = [
        'PRESUBMIT_test.py', r'^third_party/rust/chromium_crates_io/vendor/.*'
    ]

    def _FilterFile(affected_file):
        return input_api.FilterSourceFile(affected_file,
                                          files_to_skip=files_to_skip)

    # Monorail bug IDs are all less than or equal to 1524553 so check that all
    # bugs in TODOs are greater than that value.
    pattern = input_api.re.compile(r'.*\bTODO\([^\)0-9]*([0-9]+)\).*')
    problems = []
    for f in input_api.AffectedSourceFiles(_FilterFile):
        for line_number, line in f.ChangedContents():
            match = pattern.match(line)
            if match and int(match.group(1)) <= 1524553:
                problems.append(f'{f.LocalPath()}: {line_number}\n    {line}')

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'TODOs should use the new Chromium Issue Tracker IDs which can '
                'be found by navigating to the bug. See '
                'https://crbug.com/336778624 for more details.', problems)
        ]
    else:
        return []


def CheckNoBrowserStarInUnittests(input_api, output_api):
    """Checks that unit-tests don't contain Browser* variables.
    """
    problems = []

    def FileFilter(affected_file):
        """Check unit-tests only"""
        return input_api.FilterSourceFile(
            affected_file,
            files_to_check=(r'.*unittest\.cc$', r'.*unittest\.h$'),
            files_to_skip=input_api.DEFAULT_FILES_TO_SKIP,
        )

    browser_star_pattern = input_api.re.compile(r'\bBrowser\s*\*')

    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=FileFilter):
        for line_num, line in f.ChangedContents():
            match = browser_star_pattern.search(line)
            if match:
                problems.append('  %s:%d:%s' %
                                (f.LocalPath(), line_num, match.group(0)))

    if not problems:
        return []

    WARNING_MSG = """Do not use "Browser*" type in unittest files (e.g.,
    "*unittest.cc" or "*unittest.h"). Unit tests should generally
    not depend on the full Browser class or related components. Consider
    refactoring to mock dependencies, use test-specific fakes,
    or determine if a browser_test is more appropriate.
    """
    return [output_api.PresubmitPromptWarning(WARNING_MSG, items=problems)]


def CheckBaseFeatureMacro(input_api, output_api):
    """Checks for correct usage of the BASE_FEATURE macro."""
    pattern = input_api.re.compile(
        r'\bBASE_FEATURE\s*\(\s*([^,]+)\s*,\s*([^,)]+)')
    warnings = []

    for f in input_api.AffectedFiles():
        if not f.LocalPath().endswith(('.cc', '.mm')):
            continue

        # Create a set of changed line numbers.
        changed_line_numbers = {
            line_num
            for line_num, _ in f.ChangedContents()
        }
        if not changed_line_numbers:
            continue

        lines = list(f.NewContents())
        contents = '\n'.join(lines)
        for match in pattern.finditer(contents):
            # Determine the line numbers that the match spans.
            start_line = contents.count('\n', 0, match.start()) + 1
            end_line = contents.count('\n', 0, match.end()) + 1

            # Check if any line in the match is in the set of changed lines.
            if not changed_line_numbers.intersection(
                    range(start_line, end_line + 1)):
                continue

            # Heuristic to ignore commented out macros.
            if lines[start_line - 1].strip().startswith('//'):
                continue

            param1 = match.group(1).strip()
            param2 = match.group(2).strip()

            if param2.startswith('"') and param2.endswith('"'):
                warnings.append(
                    '    %s:%d: The 3-argument BASE_FEATURE macro with a '
                    'string literal is discouraged. Use the 2-argument '
                    'version instead.' % (f.LocalPath(), start_line))

            if not input_api.re.match(r'^k[A-Z]', param1):
                warnings.append(
                    '    %s:%d: Feature identifier "%s" should start with "k" '
                    'followed by an uppercase letter.' %
                    (f.LocalPath(), start_line, param1))

    if not warnings:
        return []

    return [
        output_api.PresubmitPromptWarning('BASE_FEATURE() macro naming:',
                                          warnings)
    ]
