# Quality contract for this repo, machine-readable half. ".clang-format" decides
# how the code is laid out; this file decides what it is allowed to say. The two
# are meant to agree: FormatStyle below points clang-tidy at ".clang-format", so
# "--fix" never reformats against the house style.
#
# Run it with "make tidy" — a separate target, not part of "make", and it does
# not fail the build (WarningsAsErrors is empty). The compile flags reach
# clang-tidy after the "--", which is why no compile_commands.json is needed.
---
Checks: >
  bugprone-*,
  performance-*,
  modernize-*,
  portability-*,
  clang-analyzer-*,
  misc-definitions-in-headers,
  misc-misplaced-const,
  misc-unused-parameters,
  misc-unused-using-decls,
  readability-identifier-naming,
  readability-redundant-*,
  readability-container-size-empty,
  readability-misleading-indentation,
  readability-simplify-boolean-expr,
  readability-string-compare,
  -bugprone-easily-swappable-parameters,
  -modernize-use-trailing-return-type,
  -modernize-use-nodiscard,
  -performance-enum-size

# Why those four are off:
#   bugprone-easily-swappable-parameters — fires on any two adjacent parameters
#     of the same type, so every "(int fd, int events)" in a network codebase.
#   modernize-use-trailing-return-type — would rewrite every signature as
#     "auto f() -> T", which contradicts the Google base of ".clang-format".
#   modernize-use-nodiscard — wants [[nodiscard]] on essentially every const
#     accessor; the contract puts it where it earns its place, on Result<T>.
#   performance-enum-size — suggests a narrower underlying type for every enum;
#     pure churn on enums that hold a handful of values.

# Only our own headers. System headers are excluded by clang-tidy anyway unless
# -system-headers is passed, and standard library headers have no extension, so
# this pattern cannot reach them.
HeaderFilterRegex: '.*\.(hpp|tpp|ipp)$'

# Empty on purpose: "make tidy" reports, it does not block. A single overzealous
# check must never be able to stop the build.
WarningsAsErrors: ''

FormatStyle: file

CheckOptions:
  # Types.
  readability-identifier-naming.ClassCase: CamelCase
  readability-identifier-naming.StructCase: CamelCase
  readability-identifier-naming.UnionCase: CamelCase
  readability-identifier-naming.EnumCase: CamelCase
  readability-identifier-naming.TypeAliasCase: CamelCase
  readability-identifier-naming.TypedefCase: CamelCase
  readability-identifier-naming.TemplateParameterCase: CamelCase

  # Enumerators follow the type: EndpointKind::Listener, ListenerPause::PoolFull.
  readability-identifier-naming.EnumConstantCase: CamelCase

  readability-identifier-naming.NamespaceCase: lower_case

  # Functions and variables.
  readability-identifier-naming.FunctionCase: camelBack
  readability-identifier-naming.MethodCase: camelBack
  readability-identifier-naming.VariableCase: camelBack
  readability-identifier-naming.ParameterCase: camelBack

  # Data members: trailing underscore on the ones that are not public. A public
  # member belongs to a plain aggregate (Header{name, value}) and takes none.
  readability-identifier-naming.MemberCase: camelBack
  readability-identifier-naming.PublicMemberCase: camelBack
  readability-identifier-naming.PrivateMemberCase: camelBack
  readability-identifier-naming.PrivateMemberSuffix: _
  readability-identifier-naming.ProtectedMemberCase: camelBack
  readability-identifier-naming.ProtectedMemberSuffix: _

  # Constants are UPPER_SNAKE_CASE only where they are constants in the sense
  # that matters — namespace scope, static, or a class-level constant such as
  # ByteBuffer::CAPACITY. ConstexprVariableCase and LocalConstantCase are left
  # unset deliberately: clang-tidy only uses a style kind it has been given a
  # value for, so an unset one falls through to the next candidate, and a
  # "constexpr" inside a function lands on VariableCase and stays camelBack.
  readability-identifier-naming.GlobalConstantCase: UPPER_CASE
  readability-identifier-naming.StaticConstantCase: UPPER_CASE
  readability-identifier-naming.ClassConstantCase: UPPER_CASE
  readability-identifier-naming.MacroDefinitionCase: UPPER_CASE

  # "_foo" at namespace scope, and anything with "__", is reserved to the
  # implementation. This is the check that keeps the trailing-underscore rule
  # from drifting back to a leading one.
  bugprone-reserved-identifier.AllowedIdentifiers: ''
