// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/header_checker.h"

#include <algorithm>

#include "base/containers/queue.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "gn/build_settings.h"
#include "gn/builder.h"
#include "gn/c_include_iterator.h"
#include "gn/config.h"
#include "gn/config_values_extractors.h"
#include "gn/err.h"
#include "gn/filesystem_utils.h"
#include "gn/hash_table_base.h"
#include "gn/scheduler.h"
#include "gn/swift_values.h"
#include "gn/target.h"
#include "gn/trace.h"
#include "util/worker_pool.h"

// This class includes a list of all known files in the build and which targets
// they are in. When CheckFile is called, it identifies which targets the file
// is in. If it is in at least one binary target (like a static or shared
// library, but not a config or an action), then the toolchain is following
// the rules.
//
// The rules are:
//    1. A target lists a header as public (the default) or private (detected
//       properly).
//
//    2. A target lists a header as private. Then another target depends on the
//       first target. The second target cannot include the private header.
//       This is the more advanced check.
//
//    3. A target lists a header as public (the default). Then another target
//       depends on the first target. The second target can include the public
//       header.
//
//    4. A target lists a header. Another target that does not depend on the
//       first target cannot include the header.
//
namespace {

struct PublicGeneratedPair {
  PublicGeneratedPair() : is_public(false), is_generated(false) {}
  bool is_public;
  bool is_generated;
};

// This class makes InputFiles on the stack as it reads files to check. When
// we throw an error, the Err indicates a locatin which has a pointer to
// an InputFile that must persist as long as the Err does.
//
// To make this work, this function creates a clone of the InputFile managed
// by the InputFileManager so the error can refer to something that
// persists. This means that the current file contents will live as long as
// the program, but this is OK since we're erroring out anyway.
LocationRange CreatePersistentRange(const InputFile& input_file,
                                    const LocationRange& range) {
  InputFile* clone_input_file;
  std::vector<Token>* tokens;              // Don't care about this.
  std::unique_ptr<ParseNode>* parse_root;  // Don't care about this.

  g_scheduler->input_file_manager()->AddDynamicInput(
      input_file.name(), &clone_input_file, &tokens, &parse_root);
  clone_input_file->SetContents(input_file.contents());

  return LocationRange(Location(clone_input_file, range.begin().line_number(),
                                range.begin().column_number()),
                       Location(clone_input_file, range.end().line_number(),
                                range.end().column_number()));
}

// Given a reverse dependency chain where the target chain[0]'s includes are
// being used by chain[end] and not all deps are public, returns the string
// describing the error.
std::string GetDependencyChainPublicError(const HeaderChecker::Chain& chain) {
  std::string ret =
      "The target:\n  " +
      chain[chain.size() - 1].target->label().GetUserVisibleName(false) +
      "\nis including a file from the target:\n  " +
      chain[0].target->label().GetUserVisibleName(false) + "\n";

  // Invalid chains should always be 0 (no chain) or more than two
  // (intermediate private dependencies). 1 and 2 are impossible because a
  // target can always include headers from itself and its direct dependents.
  DCHECK(chain.size() != 1 && chain.size() != 2);
  if (chain.empty()) {
    ret += "There is no dependency chain between these targets.";
  } else {
    // Indirect dependency chain, print the chain.
    const Target* strict_target = nullptr;
    for (size_t i = 1; i < chain.size() - 1; i++) {
      if (chain[i].target->check_includes_strict()) {
        strict_target = chain[i].target;
        break;
      }
    }

    if (strict_target) {
      ret +=
          "\nPlease depend directly on the destination target.\n"
          "Including headers from the public_deps of " +
          strict_target->label().GetUserVisibleName(false) +
          " is blocked because check_includes_strict = true is enabled on it.\n"
          "check_includes_strict = true is highly recommended for all new code "
          "to ensure a correct build graph.\n";
    } else {
      ret +=
          "\nIt's usually best to depend directly on the destination target.\n"
          "In some cases, the destination target is considered a subcomponent\n"
          "of an intermediate target. In this case, the intermediate target\n"
          "should depend publicly on the destination to forward the ability\n"
          "to include headers.\n";
    }
    ret += "\nDependency chain (there may also be others):\n";

    for (int i = static_cast<int>(chain.size()) - 1; i >= 0; i--) {
      ret.append("  " + chain[i].target->label().GetUserVisibleName(false));
      if (i != 0) {
        // Identify private dependencies so the user can see where in the
        // dependency chain things went bad. Don't list this for the first link
        // in the chain since direct dependencies are OK, and listing that as
        // "private" may make people feel like they need to fix it.
        if (i == static_cast<int>(chain.size()) - 1 || chain[i - 1].is_public) {
          if (i != static_cast<int>(chain.size()) - 1 &&
              chain[i].target->check_includes_strict()) {
            ret.append(" --[check_includes_strict = true]-->");
          } else {
            ret.append(" -->");
          }
        } else {
          ret.append(" --[private]-->");
        }
      }
      ret.append("\n");
    }
  }
  return ret;
}

// Returns true if the two targets have the same label not counting the
// toolchain.
bool TargetLabelsMatchExceptToolchain(const Target* a, const Target* b) {
  return a->label().dir() == b->label().dir() &&
         a->label().name() == b->label().name();
}

// Returns true if the target |annotation_on| includes a friend annotation
// that allows |is_marked_friend| as a friend.
bool FriendMatches(const Target* annotation_on,
                   const Target* is_marked_friend) {
  return LabelPattern::VectorMatches(annotation_on->friends(),
                                     is_marked_friend->label());
}

}  // namespace

HeaderChecker::HeaderChecker(const BuildSettings* build_settings,
                             const std::vector<const Target*>& targets,
                             bool check_generated,
                             bool check_system)
    : build_settings_(build_settings),
      check_generated_(check_generated),
      check_system_(check_system),
      errors_lock_(),
      task_count_cv_() {
  for (auto* target : targets)
    AddTargetToFileMap(target, &file_map_);
}

HeaderChecker::~HeaderChecker() = default;

bool HeaderChecker::Run(const std::vector<const Target*>& to_check,
                        bool force_check,
                        std::vector<Violation>* violations) {
  FileMap files_to_check;
  for (auto* check : to_check) {
    // This function will get called with all target types, but check only
    // applies to binary targets.
    if (check->IsBinary())
      AddTargetToFileMap(check, &files_to_check);
  }

  WorkerPool pool;
  {
    ScopedTrace precompute_trace(TraceItem::TRACE_CHECK_HEADERS,
                                 "Precompute reachability");
    std::set<const Target*> targets_to_precompute;
    for (const auto& file : files_to_check) {
      for (const auto& target_info : file.second.targets) {
        if (target_info.target->check_includes())
          targets_to_precompute.insert(target_info.target);
      }
    }

    if (!targets_to_precompute.empty()) {
      task_count_.Increment();
      for (const auto* target : targets_to_precompute) {
        task_count_.Increment();
        pool.PostTask([this, target]() {
          ReachabilityCache& cache = GetReachabilityCacheForTarget(target);
          cache.PerformDependencyWalk(true);
          cache.PerformDependencyWalk(false);
          if (!task_count_.Decrement()) {
            std::unique_lock<std::mutex> lock(task_count_lock_);
            task_count_cv_.notify_one();
          }
        });
      }

      if (!task_count_.Decrement()) {
        std::unique_lock<std::mutex> lock(task_count_lock_);
        task_count_cv_.notify_one();
      }

      std::unique_lock<std::mutex> lock(task_count_lock_);
      while (!task_count_.IsZero())
        task_count_cv_.wait(lock);
    }
  }

  RunCheckOverFiles(files_to_check, force_check, &pool);

  if (violations_.empty())
    return true;
  if (violations)
    *violations = violations_;
  return false;
}

void HeaderChecker::RunCheckOverFiles(const FileMap& files,
                                      bool force_check,
                                      WorkerPool* pool) {
  task_count_.Increment();

  for (const auto& file : files) {
    // Only check C-like source files (RC files also have includes).
    const SourceFile::Type type = file.second.file.GetType();
    if (type != SourceFile::SOURCE_CPP && type != SourceFile::SOURCE_H &&
        type != SourceFile::SOURCE_C && type != SourceFile::SOURCE_M &&
        type != SourceFile::SOURCE_MM && type != SourceFile::SOURCE_RC)
      continue;

    if (!check_generated_) {
      // If any target marks it as generated, don't check it. We have to check
      // file_map_, which includes all known files; files only includes those
      // being checked.
      bool is_generated = false;
      auto found = file_map_.find(file.first);
      DCHECK(found != file_map_.end());
      for (const auto& vect_i : found->second.targets)
        is_generated |= vect_i.is_generated;
      if (is_generated)
        continue;
    }

    TargetVector targets_to_check;
    for (const auto& vect_i : file.second.targets) {
      if (vect_i.target->check_includes()) {
        targets_to_check.push_back(vect_i);
      }
    }
    if (targets_to_check.empty())
      continue;

    task_count_.Increment();
    pool->PostTask([this, targets = std::move(targets_to_check),
                    file = file.second.file]() { DoWork(targets, file); });
  }

  if (!task_count_.Decrement()) {
    std::unique_lock<std::mutex> lock(task_count_lock_);
    task_count_cv_.notify_one();
  }

  // Wait for all tasks posted by this method to complete.
  std::unique_lock<std::mutex> auto_lock(task_count_lock_);
  while (!task_count_.IsZero())
    task_count_cv_.wait(auto_lock);
}

void HeaderChecker::DoWork(const TargetVector& targets,
                           const SourceFile& file) {
  std::vector<Violation> violations;
  if (!CheckFile(targets, file, &violations)) {
    std::lock_guard<std::mutex> lock(errors_lock_);
    violations_.insert(violations_.end(),
                       std::make_move_iterator(violations.begin()),
                       std::make_move_iterator(violations.end()));
  }

  if (!task_count_.Decrement()) {
    // Signal |task_count_cv_| when |task_count_| becomes zero.
    std::unique_lock<std::mutex> auto_lock(task_count_lock_);
    task_count_cv_.notify_one();
  }
}

// static
void HeaderChecker::AddTargetToFileMap(const Target* target, FileMap* dest) {
  // Files in the sources have this public bit by default.
  bool default_public = target->all_headers_public();

  std::unordered_map<SourceFile, PublicGeneratedPair> files_to_public;

  // First collect the normal files, they get the default visibility. If you
  // depend on the compiled target, it should be enough to be able to include
  // the header.
  for (const auto& source : target->sources()) {
    files_to_public[source].is_public = default_public;
  }

  // Add in the public files, forcing them to public. This may overwrite some
  // entries, and it may add new ones.
  if (default_public)  // List only used when default is not public.
    DCHECK(target->public_headers().empty());
  for (const auto& source : target->public_headers()) {
    files_to_public[source].is_public = true;
  }

  // If target generates a swiftmodule, then
  //  - it may use a bridge header which has default visibility
  //  - it may generate public header which must be considered public
  if (target->builds_swift_module()) {
    const SourceFile& bridge_header = target->swift_values().bridge_header();
    if (!bridge_header.is_null()) {
      files_to_public[bridge_header].is_public = default_public;
    }

    std::vector<SourceFile> outputs;
    target->swift_values().GetOutputsAsSourceFiles(target, &outputs);

    for (const SourceFile& output : outputs) {
      if (output.GetType() == SourceFile::SOURCE_H) {
        PublicGeneratedPair* pair = &files_to_public[output];
        pair->is_public = true;
        pair->is_generated = true;
      }
    }
  }

  // Add in outputs from actions. These are treated as public (since if other
  // targets can't use them, then there wouldn't be any point in outputting).
  std::vector<SourceFile> outputs;
  target->action_values().GetOutputsAsSourceFiles(target, &outputs);
  for (const auto& output : outputs) {
    PublicGeneratedPair* pair = &files_to_public[output];
    pair->is_public = true;
    pair->is_generated = true;
  }

  // Add the merged list to the master list of all files.
  for (const auto& cur : files_to_public) {
    dest->try_emplace(cur.first.value(), FileInformation{cur.first, {}})
        .first->second.targets.emplace_back(target, cur.second.is_public,
                                            cur.second.is_generated);
  }
}

bool HeaderChecker::IsFileInOuputDir(const SourceFile& file) const {
  const std::string& build_dir = build_settings_->build_dir().value();
  return file.value().starts_with(build_dir);
}

SourceFile HeaderChecker::SourceFileForInclude(
    const IncludeStringWithLocation& include,
    const std::vector<SourceDir>& include_dirs,
    const InputFile& source_file) const {
  std::string_view inc = include.contents;
  if (inc.empty())
    return SourceFile();

  auto find_file = [this](std::string_view path) -> const SourceFile* {
    auto it = file_map_.find(path);
    return it == file_map_.end() ? nullptr : &it->second.file;
  };

  if (inc.starts_with("//") || IsPathAbsolute(inc)) {
    const SourceFile* found = find_file(
        ResolveRelative(inc, std::string(), true, std::string_view()));
    return found ? *found : SourceFile();
  }

  std::string buffer;
  buffer.reserve(128);
  auto find_in_dir = [&](const SourceDir& dir) -> const SourceFile* {
    buffer.assign(dir.value());
    buffer.append(inc);
    NormalizePath(&buffer);
    return find_file(buffer);
  };

  if (!include.system_style_include) {
    if (const SourceFile* found = find_in_dir(source_file.dir()))
      return *found;
  }
  for (const SourceDir& dir : include_dirs) {
    if (const SourceFile* found = find_in_dir(dir))
      return *found;
  }
  return SourceFile();
}

void HeaderChecker::ReachabilityCache::PerformDependencyWalk(bool permitted) {
  // Conduct the actual BFS.
  if (permitted ? permitted_complete_.load(std::memory_order_relaxed)
                : any_complete_.load(std::memory_order_relaxed)) {
    return;
  }

  BreadcrumbTable& breadcrumbs =
      permitted ? permitted_breadcrumbs_ : any_breadcrumbs_;

  // work_queue maintains a queue of targets which need to be considered as part
  // of dependency chain, in the order they were first traversed. Each time a
  // new transitive dependency of source_target_ is discovered for the first
  // time, it is added to work_queue and a "breadcrumb" is added, indicating
  // which target it was reached from when first discovered.
  base::queue<const Target*> work_queue;
  work_queue.push(source_target_);
  breadcrumbs.Insert(source_target_, nullptr, true);

  while (!work_queue.empty()) {
    const Target* target = work_queue.front();
    work_queue.pop();

    if (permitted && target != source_target_ &&
        target->check_includes_strict()) {
      continue;
    }

    for (const auto& dep : target->public_deps()) {
      if (breadcrumbs.Insert(dep.ptr, target, true))
        work_queue.push(dep.ptr);
    }

    if (!permitted || target == source_target_) {
      // Consider all dependencies since all target paths are allowed, so add
      // in private ones. Also do this the first time through the loop, since
      // a target can include headers from its direct deps regardless of
      // public/private-ness.
      for (const auto& dep : target->private_deps()) {
        if (breadcrumbs.Insert(dep.ptr, target, false))
          work_queue.push(dep.ptr);
      }
    }
  }
  if (permitted) {
    permitted_complete_.store(true, std::memory_order_release);
  } else {
    any_complete_.store(true, std::memory_order_release);
  }
}

bool HeaderChecker::ReachabilityCache::SearchForDependencyTo(
    const Target* search_for,
    bool permitted,
    Chain* chain) {
  if (permitted ? permitted_complete_.load(std::memory_order_acquire)
                : any_complete_.load(std::memory_order_acquire)) {
    return SearchBreadcrumbs(search_for, permitted, chain);
  }

  {
    std::unique_lock<std::shared_mutex> write_lock(lock_);
    if (!(permitted ? permitted_complete_.load(std::memory_order_relaxed)
                    : any_complete_.load(std::memory_order_relaxed))) {
      PerformDependencyWalk(permitted);
    }
  }

  return SearchBreadcrumbs(search_for, permitted, chain);
}

bool HeaderChecker::ReachabilityCache::SearchBreadcrumbs(
    const Target* search_for,
    bool permitted,
    Chain* chain) const {
  const BreadcrumbTable& breadcrumbs =
      permitted ? permitted_breadcrumbs_ : any_breadcrumbs_;
  ChainLink incoming_link = breadcrumbs.GetLink(search_for);
  if (!incoming_link.target)
    return false;

  // Found it! Reconstruct the chain.
  chain->clear();
  const Target* cur = search_for;
  while (cur != source_target_) {
    ChainLink link = breadcrumbs.GetLink(cur);
    chain->push_back(ChainLink(cur, link.is_public));
    cur = link.target;
  }
  chain->push_back(ChainLink(source_target_, true));

  return true;
}

bool HeaderChecker::CheckFile(const TargetVector& targets,
                              const SourceFile& file,
                              std::vector<Violation>* violations) const {
  ScopedTrace trace(TraceItem::TRACE_CHECK_HEADER, file.value());

  // Sometimes you have generated source files included as sources in another
  // target. These won't exist at checking time. Since we require all generated
  // files to be somewhere in the output tree, we can just check the name to
  // see if they should be skipped.
  if (!check_generated_ && IsFileInOuputDir(file))
    return true;

  base::FilePath path = build_settings_->GetFullPath(file);
  std::string contents;
  if (!base::ReadFileToString(path, &contents)) {
    // A missing (not yet) generated file is an acceptable problem
    // considering this code does not understand conditional includes.
    if (IsFileInOuputDir(file))
      return true;

    for (const TargetInfo& from_target_info : targets) {
      const Target* from_target = from_target_info.target;
      violations->emplace_back(
          Err(from_target->defined_from(), "Source file not found.",
              "The target:\n  " +
                  from_target->label().GetUserVisibleName(false) +
                  "\nhas a source file:\n  " + file.value() +
                  "\nwhich was not found."),
          from_target, file, SourceFile());
    }
    return false;
  }

  InputFile input_file(file);
  input_file.SetContents(contents);

  std::vector<IncludeStringWithLocation> includes;
  CIncludeIterator iter(&input_file);
  IncludeStringWithLocation include;
  while (iter.GetNextIncludeString(&include)) {
    if (include.system_style_include && !check_system_)
      continue;
    includes.push_back(include);
  }

  if (includes.empty())
    return true;

  size_t violations_count_before = violations->size();

  for (const TargetInfo& from_target_info : targets) {
    const Target* from_target = from_target_info.target;
    std::vector<SourceDir> include_dirs;
    for (ConfigValuesIterator target_iter(from_target); !target_iter.done();
         target_iter.Next()) {
      const std::vector<SourceDir>& target_include_dirs =
          target_iter.cur().include_dirs();
      include_dirs.insert(include_dirs.end(), target_include_dirs.begin(),
                          target_include_dirs.end());
    }

    ReachabilityCache& from_target_cache =
        GetReachabilityCacheForTarget(from_target);

    for (const auto& inc : includes) {
      SourceFile included_file =
          SourceFileForInclude(inc, include_dirs, input_file);
      if (!included_file.is_null()) {
        std::vector<Err> include_errors;
        CheckInclude(from_target_cache,
                     from_target_info.is_public &&
                         file.GetType() == SourceFile::SOURCE_H,
                     input_file, included_file, inc.location, &include_errors);
        for (auto& e : include_errors) {
          violations->emplace_back(std::move(e), from_target, file,
                                   std::move(included_file));
        }
      }
    }
  }

  return violations->size() == violations_count_before;
}

// If the file exists:
//  - The header must be in the public section of a target, or it must
//    be in the sources with no public list (everything is implicitly public).
//  - The dependency path to the included target must follow only public_deps.
//  - If there are multiple targets with the header in it, only one need be
//    valid for the check to pass.
void HeaderChecker::CheckInclude(ReachabilityCache& from_target_cache,
                                 bool is_public_header,
                                 const InputFile& source_file,
                                 const SourceFile& include_file,
                                 const LocationRange& range,
                                 std::vector<Err>* errors) const {
  // Assume if the file isn't declared in our sources that we don't need to
  // check it. It would be nice if we could give an error if this happens, but
  // our include finder is too primitive and returns all includes, even if
  // they're in a #if not executed in the current build. In that case, it's
  // not unusual for the buildfiles to not specify that header at all.
  FileMap::const_iterator found = file_map_.find(include_file.value());
  if (found == file_map_.end())
    return;

  const TargetVector& targets = found->second.targets;
  Chain chain;  // Prevent reallocating in the loop.

  const Target* from_target = from_target_cache.source_target();

  // If the file is unknown in the current toolchain (rather than being private
  // or in a target not visible to the current target), ignore it. This is a
  // bit of a hack to account for the fact that the include finder doesn't
  // understand the preprocessor.
  //
  // When not cross-compiling, if a platform specific header is conditionally
  // included in the build, and preprocessor conditions around #includes of
  // that match the build conditions, everything will be OK because the file
  // won't be known to GN even though the #include finder identified the file.
  //
  // Cross-compiling breaks this. When compiling Android on Linux, for example,
  // we might see both Linux and Android definitions of a target and know
  // about the union of all headers in the build. Since the #include finder
  // ignores preprocessor, we will find the Linux headers in the Android
  // build and note that a dependency from the Android target to the Linux
  // one is missing (these might even be the same target in different
  // toolchains!).
  bool present_in_current_toolchain = false;
  for (const auto& target : targets) {
    if (from_target->label().ToolchainsEqual(target.target->label())) {
      present_in_current_toolchain = true;
      break;
    }
  }
  if (!present_in_current_toolchain)
    return;

  // For all targets containing this file, we require that at least one be
  // a direct or public dependency of the current target, and either (1) the
  // header is public within the target, or (2) there is a friend definition
  // allowlisting the includor.
  //
  // If there is more than one target containing this header, we may encounter
  // some error cases before finding a good one. This error stores the previous
  // one encountered, which we may or may not throw away.
  Err last_error;

  bool found_dependency = false;
  for (const auto& target : targets) {
    // We always allow source files in a target to include headers also in that
    // target, unless strict checking is enabled and a public header includes
    // a private header.
    const Target* to_target = target.target;
    if (to_target == from_target) {
      if (from_target->check_includes_strict() && is_public_header &&
          !target.is_public) {
        last_error = Err(
            CreatePersistentRange(source_file, range),
            "Public headers cannot include private headers of the same target.",
            "The public header:\n  " + source_file.name().value() +
                "\nis including a private header of the same target:\n  " +
                include_file.value() +
                "\nEither make the included header public, make the includer "
                "private,\n"
                "or make a source_set containing public = [private_headers] "
                "and add it to public_deps.");
        errors->push_back(std::move(last_error));
      }
      return;
    }

    bool is_permitted_chain = false;
    if (IsDependencyOf(to_target, from_target_cache, &chain,
                       &is_permitted_chain)) {
      DCHECK(chain.size() >= 2);
      DCHECK(chain[0].target == to_target);
      DCHECK(chain[chain.size() - 1].target == from_target);
      found_dependency = true;

      bool effectively_public =
          target.is_public || FriendMatches(to_target, from_target);

      if (effectively_public && is_permitted_chain) {
        if (from_target->check_includes_strict() && is_public_header &&
            !chain[chain.size() - 2].is_public) {
          last_error = Err(
              CreatePersistentRange(source_file, range),
              "Public headers cannot include private dependencies.",
              "The public header:\n  " + source_file.name().value() +
                  "\nis including a header from private dependency:\n  " +
                  to_target->label().GetUserVisibleName(false) +
                  "\nEither move the dependency to public_deps, or make this "
                  "header private.");
          continue;
        }
        // This one is OK, we're done.
        last_error = Err();
        break;
      }

      // Diagnose the error.
      if (!effectively_public) {
        // Danger: must call CreatePersistentRange to put in Err.
        last_error = Err(CreatePersistentRange(source_file, range),
                         "Including a private header.",
                         "This file is private to the target " +
                             target.target->label().GetUserVisibleName(false));
      } else if (!is_permitted_chain) {
        last_error = Err(CreatePersistentRange(source_file, range),
                         "Can't include this header from here.",
                         GetDependencyChainPublicError(chain));
      } else {
        NOTREACHED();
      }
    } else if (to_target->allow_circular_includes_from().find(
                   from_target->label()) !=
               to_target->allow_circular_includes_from().end()) {
      // Not a dependency, but this include is allowlisted from the destination.
      found_dependency = true;
      last_error = Err();
      break;
    }
  }

  if (!found_dependency || last_error.has_error()) {
    if (!found_dependency) {
      DCHECK(!last_error.has_error());
      Err err = MakeUnreachableError(source_file, range, from_target, targets);
      errors->push_back(std::move(err));
    } else {
      // Found at least one dependency chain above, but it had an error.
      errors->push_back(std::move(last_error));
    }
    return;
  }

  // One thing we didn't check for is targets that expose their dependents
  // headers in their own public headers.
  //
  // Say we have A -> B -> C. If C has public_configs, everybody getting headers
  // from C should get the configs also or things could be out-of-sync. Above,
  // we check for A including C's headers directly, but A could also include a
  // header from B that in turn includes a header from C.
  //
  // There are two ways to solve this:
  //  - If a public header in B includes C, force B to publicly depend on C.
  //    This is possible to check, but might be super annoying because most
  //    targets (especially large leaf-node targets) don't declare
  //    public/private headers and you'll get lots of false positives.
  //
  //  - Save the includes found in each file and actually compute the graph of
  //    includes to detect when A implicitly includes C's header. This will not
  //    have the annoying false positive problem, but is complex to write.
}

HeaderChecker::ReachabilityCache& HeaderChecker::GetReachabilityCacheForTarget(
    const Target* target) const {
  size_t shard_index = target->label().hash() % kNumShards;
  auto& shard = dependency_cache_[shard_index];
  std::unique_lock<std::shared_mutex> lock(shard.lock);
  auto it = shard.cache.find(target);
  if (it == shard.cache.end()) {
    it =
        shard.cache.emplace(target, std::make_unique<ReachabilityCache>(target))
            .first;
  }
  return *it->second;
}

bool HeaderChecker::IsDependencyOf(const Target* search_for,
                                   ReachabilityCache& from_target_cache,
                                   Chain* chain,
                                   bool* is_permitted) const {
  const Target* search_from = from_target_cache.source_target();
  if (search_for == search_from) {
    // A target is always visible from itself.
    *is_permitted = true;
    return false;
  }

  // 1. Try permitted dependency.
  if (from_target_cache.SearchForDependencyTo(search_for, true, chain)) {
    *is_permitted = true;
    return true;
  }

  // 2. Try any dependency.
  if (from_target_cache.SearchForDependencyTo(search_for, false, chain)) {
    *is_permitted = false;
    return true;
  }

  return false;
}

Err HeaderChecker::MakeUnreachableError(const InputFile& source_file,
                                        const LocationRange& range,
                                        const Target* from_target,
                                        const TargetVector& targets) {
  // Normally the toolchains will all match, but when cross-compiling, we can
  // get targets with more than one toolchain in the list of possibilities.
  std::vector<const Target*> targets_with_matching_toolchains;
  std::vector<const Target*> targets_with_other_toolchains;
  for (const TargetInfo& candidate : targets) {
    if (candidate.target->toolchain() == from_target->toolchain())
      targets_with_matching_toolchains.push_back(candidate.target);
    else
      targets_with_other_toolchains.push_back(candidate.target);
  }

  // It's common when cross-compiling to have a target with the same file in
  // more than one toolchain. We could output all of them, but this is
  // generally confusing to people (most end-users won't understand toolchains
  // well).
  //
  // So delete any candidates in other toolchains that also appear in the same
  // toolchain as the from_target.
  for (int other_index = 0;
       other_index < static_cast<int>(targets_with_other_toolchains.size());
       other_index++) {
    for (const Target* cur_matching : targets_with_matching_toolchains) {
      if (TargetLabelsMatchExceptToolchain(
              cur_matching, targets_with_other_toolchains[other_index])) {
        // Found a duplicate, erase it.
        targets_with_other_toolchains.erase(
            targets_with_other_toolchains.begin() + other_index);
        other_index--;
        break;
      }
    }
  }

  // Only display toolchains on labels if they don't all match.
  bool include_toolchain = !targets_with_other_toolchains.empty();

  std::string msg = "It is not in any dependency of\n  " +
                    from_target->label().GetUserVisibleName(include_toolchain);
  msg += "\nThe include file is in the target(s):\n";
  for (auto* target : targets_with_matching_toolchains)
    msg += "  " + target->label().GetUserVisibleName(include_toolchain) + "\n";
  for (auto* target : targets_with_other_toolchains)
    msg += "  " + target->label().GetUserVisibleName(include_toolchain) + "\n";
  if (targets_with_other_toolchains.size() +
          targets_with_matching_toolchains.size() >
      1)
    msg += "at least one of ";
  msg += "which should somehow be reachable.\n";
  msg +=
      "This might be a false alarm if you are using conditional include. "
      "See \"gn help nogncheck\".";

  // Danger: must call CreatePersistentRange to put in Err.
  return Err(CreatePersistentRange(source_file, range), "Include not allowed.",
             msg);
}
