// Copyright 2019 The Fuchsia 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 <lib/fit/function.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <set>

#include <fidl/findings.h>
#include <fidl/linter.h>
#include <fidl/names.h>
#include <fidl/raw_ast.h>
#include <fidl/utils.h>

namespace fidl {
namespace linter {

namespace {

// Convert the SourceElement (start- and end-tokens within the SourceFile)
// to a std::string_view, spanning from the beginning of the start token, to the end
// of the end token. The three methods support classes derived from
// SourceElement, by reference, pointer, or unique_ptr.
static std::string_view to_string_view(const fidl::raw::SourceElement& element) {
  return element.span().data();
}

template <typename SourceElementSubtype>
std::string_view to_string_view(const std::unique_ptr<SourceElementSubtype>& element_ptr) {
  static_assert(std::is_base_of<fidl::raw::SourceElement, SourceElementSubtype>::value,
                "Template parameter type is not derived from SourceElement");
  return to_string_view(element_ptr.get());
}

// Convert the SourceElement to a std::string, using the method described above
// for std::string_view.
static std::string to_string(const fidl::raw::SourceElement& element) {
  return std::string(to_string_view(element));
}

template <typename SourceElementSubtype>
std::string to_string(const std::unique_ptr<SourceElementSubtype>& element_ptr) {
  static_assert(std::is_base_of<fidl::raw::SourceElement, SourceElementSubtype>::value,
                "Template parameter type is not derived from SourceElement");
  return to_string(*element_ptr.get());
}

}  // namespace

std::string Linter::MakeCopyrightBlock() {
  std::string copyright_block;
  for (auto line : kCopyrightLines) {
    copyright_block.append("\n");
    copyright_block.append(line);
  }
  return copyright_block;
}

const std::set<std::string>& Linter::permitted_library_prefixes() const {
  return kPermittedLibraryPrefixes;
}

std::string Linter::kPermittedLibraryPrefixesas_string() const {
  std::ostringstream ss;
  bool first = true;
  for (auto& prefix : permitted_library_prefixes()) {
    if (!first) {
      ss << " | ";
    }
    ss << prefix;
    first = false;
  }
  return ss.str();
}

// Returns itself. Overloaded to support alternative type references by
// pointer and unique_ptr as needed.
static const fidl::raw::SourceElement& GetElementAsRef(
    const fidl::raw::SourceElement& source_element) {
  return source_element;
}

static const fidl::raw::SourceElement& GetElementAsRef(const fidl::raw::SourceElement* element) {
  return GetElementAsRef(*element);
}

// Returns the pointed-to element as a reference.
template <typename SourceElementSubtype>
const fidl::raw::SourceElement& GetElementAsRef(
    const std::unique_ptr<SourceElementSubtype>& element_ptr) {
  static_assert(std::is_base_of<fidl::raw::SourceElement, SourceElementSubtype>::value,
                "Template parameter type is not derived from SourceElement");
  return GetElementAsRef(element_ptr.get());
}
// Add a finding with |Finding| constructor arguments.
// This function is const because the Findings (TreeVisitor) object
// is not modified. It's Findings object (not owned) is updated.
Finding* Linter::AddFinding(SourceSpan span, std::string check_id, std::string message) {
  auto result = current_findings_.emplace(new Finding(span, check_id, message));
  // Future checks may need to allow multiple findings of the
  // same check ID at the same location.
  assert(result.second && "Duplicate key. Check criteria in Finding.operator==() and operator<()");
  return result.first->get();
}

// Add a finding with optional suggestion and replacement
const Finding* Linter::AddFinding(SourceSpan span, const CheckDef& check,
                                  Substitutions substitutions, std::string suggestion_template,
                                  std::string replacement_template) {
  auto* finding = AddFinding(span, check.id(), check.message_template().Substitute(substitutions));
  if (finding == nullptr) {
    return nullptr;
  }
  if (suggestion_template.size() > 0) {
    if (replacement_template.size() == 0) {
      finding->SetSuggestion(TemplateString(suggestion_template).Substitute(substitutions));
    } else {
      finding->SetSuggestion(TemplateString(suggestion_template).Substitute(substitutions),
                             TemplateString(replacement_template).Substitute(substitutions));
    }
  }
  return finding;
}

// Add a finding from a SourceElement
template <typename SourceElementSubtypeRefOrPtr>
const Finding* Linter::AddFinding(const SourceElementSubtypeRefOrPtr& element,
                                  const CheckDef& check, Substitutions substitutions,
                                  std::string suggestion_template,
                                  std::string replacement_template) {
  return AddFinding(GetElementAsRef(element).span(), check, substitutions, suggestion_template,
                    replacement_template);
}

CheckDef Linter::DefineCheck(std::string check_id, std::string message_template) {
  auto result = checks_.emplace(check_id, TemplateString(message_template));
  assert(result.second && "DefineCheck called with a duplicate check_id");
  return *result.first;
}

// Returns true if no new findings were generated
bool Linter::Lint(std::unique_ptr<raw::File> const& parsed_source, Findings* findings,
                  std::set<std::string>* excluded_checks_not_found) {
  auto initial_findings_size = findings->size();
  callbacks_.Visit(parsed_source);
  for (auto& finding_ptr : current_findings_) {
    auto check_id = finding_ptr->subcategory();
    if (excluded_checks_not_found && !excluded_checks_not_found->empty()) {
      excluded_checks_not_found->erase(check_id);
    }
    bool is_included = included_check_ids_.find(check_id) != included_check_ids_.end();
    bool is_excluded =
        exclude_by_default_ || excluded_check_ids_.find(check_id) != excluded_check_ids_.end();
    if (!is_excluded || is_included) {
      findings->emplace_back(std::move(*finding_ptr));
    }
  }
  current_findings_.clear();
  return findings->size() == initial_findings_size;
}

void Linter::NewFile(const raw::File& element) {
  // Reset file state variables (for a new file)
  line_comments_checked_ = 0;
  added_invalid_copyright_finding_ = false;
  good_copyright_lines_found_ = 0;
  copyright_date_ = "";

  auto& prefix_component = element.library_name->components.front();
  library_prefix_ = to_string(prefix_component);

  library_is_platform_source_library_ =
      (kPermittedLibraryPrefixes.find(library_prefix_) != kPermittedLibraryPrefixes.end());

  filename_ = element.span().source_file().filename();

  file_is_in_platform_source_tree_ = false;

  auto in_fuchsia_dir_regex = std::regex(R"REGEX(\bfuchsia/)REGEX");
  if (std::regex_search(filename_, in_fuchsia_dir_regex)) {
    file_is_in_platform_source_tree_ = true;
  } else {
    file_is_in_platform_source_tree_ = std::ifstream(filename_.c_str()).good();
  }

  if (library_prefix_ == "zx") {
    lint_style_ = LintStyle::CStyle;
    invalid_case_for_decl_name_ =
        DefineCheck("invalid-case-for-decl-name", "${TYPE} must be named in lower_snake_case");
  } else {
    lint_style_ = LintStyle::IpcStyle;
    invalid_case_for_decl_name_ =
        DefineCheck("invalid-case-for-decl-name", "${TYPE} must be named in UpperCamelCase");
  }

  if (lint_style_ == LintStyle::IpcStyle && !library_is_platform_source_library_) {
    // TODO(fxbug.dev/7871): Implement more specific test,
    // comparing proposed library prefix to actual
    // source path.
    std::string replacement = "fuchsia, perhaps?";
    AddFinding(element.library_name, kLibraryPrefixCheck,
               {
                   {"ORIGINAL", library_prefix_},
                   {"REPLACEMENT", replacement},
               },
               "change '${ORIGINAL}' to ${REPLACEMENT}", "${REPLACEMENT}");
  }

  // Library names should not have more than four components.
  if (element.library_name->components.size() > 4) {
    AddFinding(element.library_name, kLibraryNameDepthCheck);
  }

  // Library name is not checked for CStyle because it must be simply "zx".
  if (lint_style_ == LintStyle::IpcStyle) {
    for (const auto& component : element.library_name->components) {
      if (std::regex_match(to_string(component), kDisallowedLibraryComponentRegex)) {
        AddFinding(component, kLibraryNameComponentCheck);
        break;
      }
    }
  }
  EnterContext("library", NameLibrary(element.library_name->components), kRepeatsLibraryNameCheck);
}

const Finding* Linter::CheckCase(std::string type,
                                 const std::unique_ptr<raw::Identifier>& identifier,
                                 const CheckDef& check_def, const CaseType& case_type) {
  std::string id = to_string(identifier);
  if (!case_type.matches(id)) {
    return AddFinding(identifier, check_def,
                      {
                          {"TYPE", type},
                          {"IDENTIFIER", id},
                          {"REPLACEMENT", case_type.convert(id)},
                      },
                      "change '${IDENTIFIER}' to '${REPLACEMENT}'", "${REPLACEMENT}");
  }
  return nullptr;
}

void Linter::CheckRepeatedName(std::string type,
                               const std::unique_ptr<raw::Identifier>& identifier) {
  std::string id = to_string(identifier);
  auto split_id = utils::id_to_words(id, kStopWords);
  std::set<std::string> words;
  words.insert(split_id.begin(), split_id.end());
  for (auto& context : context_stack_) {
    std::set<std::string> repeats;
    std::set_intersection(words.begin(), words.end(), context.words().begin(),
                          context.words().end(), std::inserter(repeats, repeats.begin()));
    if (!repeats.empty()) {
      context.AddRepeatsContextNames(type, identifier->span(), repeats);
    }
  }
}

const Finding* Linter::AddRepeatedNameFinding(const Context& context,
                                              const Context::RepeatsContextNames& name_repeater) {
  std::string repeated_names;
  for (const auto& repeat : name_repeater.repeats) {
    if (!repeated_names.empty()) {
      repeated_names.append(", ");
    }
    repeated_names.append(repeat);
  }
  return AddFinding(name_repeater.span, context.context_check(),
                    {
                        {"TYPE", name_repeater.type},
                        {"REPEATED_NAMES", repeated_names},
                        {"CONTEXT_TYPE", context.type()},
                        {"CONTEXT_ID", context.id()},
                    });
}

std::string Linter::GetCopyrightSuggestion() {
  auto copyright_block = kCopyrightBlock;
  if (!copyright_date_.empty()) {
    copyright_block = TemplateString(copyright_block).Substitute({{"YYYY", copyright_date_}});
  }
  if (good_copyright_lines_found_ == 0) {
    return "Insert missing header:\n" + copyright_block;
  } else {
    return "Update your header with:\n" + copyright_block;
  }
}

void Linter::AddInvalidCopyrightFinding(SourceSpan span) {
  if (!added_invalid_copyright_finding_) {
    added_invalid_copyright_finding_ = true;
    AddFinding(span, kInvalidCopyrightCheck, {}, GetCopyrightSuggestion());
  }
}

void Linter::CheckInvalidCopyright(SourceSpan span, std::string line_comment,
                                   std::string line_to_match) {
  if (line_comment == line_to_match ||
      // TODO(66908): Remove this branch once all platform FIDL files are updated.
      line_comment == line_to_match + " All rights reserved.") {
    good_copyright_lines_found_++;
    return;
  }
  if (CopyrightCheckIsComplete()) {
    return;
  }
  auto end_it = line_comment.end();
  if (line_comment.size() > line_to_match.size()) {
    end_it = line_comment.begin() + line_to_match.size();
  }
  auto first_mismatch = std::mismatch(line_comment.begin(), end_it, line_to_match.begin());
  auto index = first_mismatch.first - line_comment.begin();
  if (index > 0) {
    std::string_view error_view = span.data();
    error_view.remove_prefix(index);
    auto& source_file = span.source_file();
    span = SourceSpan(error_view, source_file);
  }
  AddInvalidCopyrightFinding(span);
}

bool Linter::CopyrightCheckIsComplete() {
  return !file_is_in_platform_source_tree_ || added_invalid_copyright_finding_ ||
         good_copyright_lines_found_ >= kCopyrightLines.size();
}

void Linter::ExitContext() {
  Context context = std::move(context_stack_.front());
  context_stack_.pop_front();

  // Check the |RepeatsContextNames| objects in context.name_repeaters(), and
  // produce Finding objects for any identifier that is not allowed to repeat
  // a name from this |Context|.
  //
  // This check addresses the FIDL Rubric rule:
  //
  //     Member names must not repeat names from the enclosing type (or
  //     library) unless the member name is ambiguous without a name from
  //     the enclosing type...
  //
  //     ...a type DeviceToRoom--that associates a smart device with the room
  //     it's located in--may need to have members device_id and room_name,
  //     because id and name are ambiguous; they could refer to either the
  //     device or the room.
  auto& repeaters = context.name_repeaters();
  for (size_t i = 1; i < repeaters.size(); i++) {
    std::set<std::string> diffs;
    std::set_difference(repeaters[i - 1].repeats.begin(), repeaters[i - 1].repeats.end(),
                        repeaters[i].repeats.begin(), repeaters[i].repeats.end(),
                        std::inserter(diffs, diffs.begin()));
    if (!diffs.empty()) {
      // If there are any differences, we have to assume they may be
      // disambiguating, which is allowed.
      return;
    }
  }
  // If multiple name repeaters in a given context all repeat the same thing,
  // then it's obvious they don't disambiguate anything, so add Findings for
  // each violator.
  for (auto& repeater : repeaters) {
    AddRepeatedNameFinding(context, repeater);
  }
}

Linter::Linter()
    : kLibraryNameDepthCheck(DefineCheck("too-many-nested-libraries",
                                         "Avoid library names with more than three dots")),
      kLibraryNameComponentCheck(
          DefineCheck("disallowed-library-name-component",
                      "Library names must not contain the following components: common, service, "
                      "util, base, f<letter>l, zx<word>")),
      kRepeatsLibraryNameCheck(
          DefineCheck("name-repeats-library-name",
                      "${TYPE} names (${REPEATED_NAMES}) must not repeat names from the "
                      "library '${CONTEXT_ID}'")),
      kLibraryPrefixCheck(DefineCheck("wrong-prefix-for-platform-source-library",
                                      "FIDL library name is not currently allowed")),
      kInvalidCopyrightCheck(
          DefineCheck("invalid-copyright-for-platform-source-library",
                      "FIDL files defined in the Platform Source Tree (i.e., defined in "
                      "fuchsia.googlesource.com) must begin with the standard copyright notice")),
      kCopyrightLines({
          // First line may also contain " All rights reserved."
          "// Copyright ${YYYY} The Fuchsia Authors.",
          "// Use of this source code is governed by a BSD-style license that can be",
          "// found in the LICENSE file.",
      }),
      kCopyrightBlock(MakeCopyrightBlock()),
      kDocAttribute("Doc"),
      kYearRegex(R"(\b(\d{4})\b)"),
      kDisallowedLibraryComponentRegex(R"(^(common|service|util|base|f[a-z]l|zx\w*)$)"),
      kPermittedLibraryPrefixes({
          "fuchsia",
          "fidl",
          "test",
      }),
      kStopWords({
          // clang-format off
          "a",
          "about",
          "above",
          "after",
          "against",
          "all",
          "an",
          "and",
          "any",
          "are",
          "as",
          "at",
          "be",
          "because",
          "been",
          "before",
          "being",
          "below",
          "between",
          "both",
          "but",
          "by",
          "can",
          "did",
          "do",
          "does",
          "doing",
          "down",
          "during",
          "each",
          "few",
          "for",
          "from",
          "further",
          "had",
          "has",
          "have",
          "having",
          "here",
          "how",
          "if",
          "in",
          "into",
          "is",
          "it",
          "its",
          "itself",
          "just",
          "more",
          "most",
          "no",
          "nor",
          "not",
          "now",
          "of",
          "off",
          "on",
          "once",
          "only",
          "or",
          "other",
          "out",
          "over",
          "own",
          "same",
          "should",
          "so",
          "some",
          "such",
          "than",
          "that",
          "the",
          "then",
          "there",
          "these",
          "this",
          "those",
          "through",
          "to",
          "too",
          "under",
          "until",
          "up",
          "very",
          "was",
          "were",
          "what",
          "when",
          "where",
          "which",
          "while",
          "why",
          "will",
          "with",
          // clang-format on
      }) {
  // clang-format off
  callbacks_.OnFile(
    [& linter = *this]
    //
    (const raw::File& element) {
      linter.NewFile(element);
    });
  // clang-format on

  callbacks_.OnLineComment(
      [&linter = *this]
      //
      (const SourceSpan& span, std::string_view line_prefix_view) {
        linter.line_comments_checked_++;
        if (linter.CopyrightCheckIsComplete() &&
            linter.line_comments_checked_ > linter.kCopyrightLines.size()) {
          return;
        }
        // span.position() is not a lightweight operation, but as long as
        // the conditions above are checked first, the line number only needs
        // to be computed a minimum number of times.
        size_t line_number = span.position().line;
        std::string line_comment = std::string(span.data());
        if (line_number > linter.kCopyrightLines.size()) {
          if (!linter.CopyrightCheckIsComplete()) {
            linter.AddInvalidCopyrightFinding(span);
          }
          return;
        }
        if (linter.copyright_date_.empty()) {
          std::smatch match_year;
          if (std::regex_search(line_comment, match_year, linter.kYearRegex)) {
            linter.copyright_date_ = match_year[1];
          }
        }
        auto line_to_match = linter.kCopyrightLines[line_number - 1];
        if (!linter.copyright_date_.empty()) {
          line_to_match =
              TemplateString(line_to_match).Substitute({{"YYYY", linter.copyright_date_}});
        }
        linter.CheckInvalidCopyright(span, line_comment, line_to_match);
      });

  callbacks_.OnExitFile([&linter = *this]
                        //
                        (const raw::File& element) {
                          if (!linter.CopyrightCheckIsComplete()) {
                            auto& source_file = element.span().source_file();
                            std::string_view error_view = source_file.data();
                            error_view.remove_suffix(source_file.data().size());
                            linter.AddInvalidCopyrightFinding(SourceSpan(error_view, source_file));
                          }
                          linter.ExitContext();
                        });

  callbacks_.OnAttribute(
      [&linter = *this,
       todo_check = DefineCheck("todo-should-not-be-doc-comment",
                                "TODO comment should use a non-flow-through comment marker"),
       regex = std::regex(R"REGEX(^[ \t]*TODO\W)REGEX")]
      //
      (const raw::Attribute& element) {
        if (element.name == linter.kDocAttribute) {
          if (std::regex_search(element.value, regex)) {
            linter.AddFinding(element, todo_check, {}, "change '///' to '//'", "//");
          }
        }
      });

  callbacks_.OnAttribute(
      [&linter = *this,
       check = DefineCheck("copyright-should-not-be-doc-comment",
                           "Copyright notice should use non-flow-through comment markers"),
       regex = std::regex(R"REGEX(^[ \t]*Copyright \d\d\d\d\W)REGEX", std::regex_constants::icase)]
      //
      (const raw::Attribute& element) {
        if (element.name == linter.kDocAttribute && std::regex_search(element.value, regex)) {
          linter.AddFinding(element, check, {}, "change '///' to '//'", "//");
        }
      });

  // TODO(fxbug.dev/7978): Remove this check after issues are resolved with
  // trailing comments in existing source and tools
  // clang-format off
  callbacks_.OnLineComment(
      [& linter = *this,
       trailing_comment_check = DefineCheck("no-trailing-comment",
                                            "Place comments above the thing being described")]
      //
      (const SourceSpan& span, std::string_view line_prefix_view) {
        if (!utils::IsBlank(line_prefix_view)) {
          linter.AddFinding(span, trailing_comment_check);
        }
      });
  // clang-format on

  callbacks_.OnUsing(
      [&linter = *this,
       case_check = DefineCheck("invalid-case-for-primitive-alias",
                                "Primitive aliases must be named in lower_snake_case"),
       &case_type = lower_snake_]
      //
      (const raw::Using& element) {
        if (element.maybe_alias != nullptr) {
          linter.CheckCase("primitive alias", element.maybe_alias, case_check, case_type);
          linter.CheckRepeatedName("primitive alias", element.maybe_alias);
        }
      });

  auto invalid_case_for_constant =
      DefineCheck("invalid-case-for-constant", "${TYPE} must be named in ALL_CAPS_SNAKE_CASE");

  callbacks_.OnConstDeclaration(
      [&linter = *this, case_check = invalid_case_for_constant, &case_type = upper_snake_]
      //
      (const raw::ConstDeclaration& element) {
        linter.CheckCase("constants", element.identifier, case_check, case_type);
        linter.CheckRepeatedName("constant", element.identifier);
        linter.in_const_declaration_ = true;
      });

  callbacks_.OnExitConstDeclaration(
      [&linter = *this]
      //
      (const raw::ConstDeclaration& element) { linter.in_const_declaration_ = false; });

  callbacks_.OnEnumMember(
      [&linter = *this, case_check = invalid_case_for_constant, &case_type = upper_snake_]
      //
      (const raw::EnumMember& element) {
        linter.CheckCase("enum members", element.identifier, case_check, case_type);
        linter.CheckRepeatedName("enum member", element.identifier);
      });

  callbacks_.OnBitsMember(
      [&linter = *this, case_check = invalid_case_for_constant, &case_type = upper_snake_]
      //
      (const raw::BitsMember& element) {
        linter.CheckCase("bitfield members", element.identifier, case_check, case_type);
        linter.CheckRepeatedName("bitfield member", element.identifier);
      });

  auto name_repeats_enclosing_type_name =
      DefineCheck("name-repeats-enclosing-type-name",
                  "${TYPE} names (${REPEATED_NAMES}) must not repeat names from the "
                  "enclosing ${CONTEXT_TYPE} '${CONTEXT_ID}'");

  callbacks_.OnProtocolDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name,
       name_contains_service_check = DefineCheck("protocol-name-includes-service",
                                                 "Protocols must not include the name 'service.'")]
      //
      (const raw::ProtocolDeclaration& element) {
        linter.CheckCase("protocols", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("protocol", element.identifier);
        for (auto word : utils::id_to_words(to_string(element.identifier))) {
          if (word == "service") {
            linter.AddFinding(element.identifier, name_contains_service_check);
            break;
          }
        }
        linter.EnterContext("protocol", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitProtocolDeclaration(
      [&linter = *this]
      //
      (const raw::ProtocolDeclaration& element) { linter.ExitContext(); });

  callbacks_.OnMethod([&linter = *this]
                      //
                      (const raw::ProtocolMethod& element) {
                        linter.CheckCase("methods", element.identifier,
                                         linter.invalid_case_for_decl_name(),
                                         linter.decl_case_type_for_style());
                        linter.CheckRepeatedName("method", element.identifier);
                      });

  callbacks_.OnEvent(
      [&linter = *this, event_check = DefineCheck("event-names-must-start-with-on",
                                                  "Event names must start with 'On'")]
      //
      (const raw::ProtocolMethod& element) {
        std::string id = to_string(element.identifier);
        auto finding =
            linter.CheckCase("events", element.identifier, linter.invalid_case_for_decl_name(),
                             linter.decl_case_type_for_style());
        if (finding && finding->suggestion().has_value()) {
          auto& suggestion = finding->suggestion().value();
          if (suggestion.replacement().has_value()) {
            id = suggestion.replacement().value();
          }
        }
        if ((id.compare(0, 2, "On") != 0) || !isupper(id[2])) {
          std::string replacement = "On" + id;
          linter.AddFinding(element.identifier, event_check,
                            {
                                {"IDENTIFIER", id},
                                {"REPLACEMENT", replacement},
                            },
                            "change '${IDENTIFIER}' to '${REPLACEMENT}'", "${REPLACEMENT}");
        }
        linter.CheckRepeatedName("event", element.identifier);
      });

  callbacks_.OnEnumDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name]
      //
      (const raw::EnumDeclaration& element) {
        linter.CheckCase("enums", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("enum", element.identifier);
        linter.EnterContext("enum", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitEnumDeclaration([&linter = *this]
                                   //
                                   (const raw::EnumDeclaration& element) { linter.ExitContext(); });

  callbacks_.OnBitsDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name]
      //
      (const raw::BitsDeclaration& element) {
        linter.CheckCase("bitfields", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("bitfield", element.identifier);
        linter.EnterContext("bitfield", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitBitsDeclaration([&linter = *this]
                                   //
                                   (const raw::BitsDeclaration& element) { linter.ExitContext(); });

  callbacks_.OnStructDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name]
      //
      (const raw::StructDeclaration& element) {
        linter.CheckCase("structs", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("struct", element.identifier);
        linter.EnterContext("struct", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitStructDeclaration(
      [&linter = *this]
      //
      (const raw::StructDeclaration& element) { linter.ExitContext(); });

  callbacks_.OnTableDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name]
      //
      (const raw::TableDeclaration& element) {
        linter.CheckCase("tables", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("table", element.identifier);
        linter.EnterContext("table", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitTableDeclaration(
      [&linter = *this]
      //
      (const raw::TableDeclaration& element) { linter.ExitContext(); });

  callbacks_.OnUnionDeclaration(
      [&linter = *this, context_check = name_repeats_enclosing_type_name]
      //
      (const raw::UnionDeclaration& element) {
        linter.CheckCase("unions", element.identifier, linter.invalid_case_for_decl_name(),
                         linter.decl_case_type_for_style());
        linter.CheckRepeatedName("union", element.identifier);
        linter.EnterContext("union", to_string(element.identifier), context_check);
      });

  callbacks_.OnExitUnionDeclaration(
      [&linter = *this]
      //
      (const raw::UnionDeclaration& element) { linter.ExitContext(); });

  auto invalid_case_for_decl_member =
      DefineCheck("invalid-case-for-decl-member", "${TYPE} must be named in lower_snake_case");

  callbacks_.OnParameter(
      [&linter = *this, case_check = invalid_case_for_decl_member, &case_type = lower_snake_]
      //
      (const raw::Parameter& element) {
        linter.CheckCase("parameters", element.identifier, case_check, case_type);
      });
  callbacks_.OnStructMember(
      [&linter = *this, case_check = invalid_case_for_decl_member, &case_type = lower_snake_]
      //
      (const raw::StructMember& element) {
        linter.CheckCase("struct members", element.identifier, case_check, case_type);
        linter.CheckRepeatedName("struct member", element.identifier);
      });
  callbacks_.OnTableMember(
      [&linter = *this, case_check = invalid_case_for_decl_member, &case_type = lower_snake_]
      //
      (const raw::TableMember& element) {
        if (element.maybe_used == nullptr)
          return;
        linter.CheckCase("table members", element.maybe_used->identifier, case_check, case_type);
        linter.CheckRepeatedName("table member", element.maybe_used->identifier);
      });
  callbacks_.OnUnionMember(
      [&linter = *this, case_check = invalid_case_for_decl_member, &case_type = lower_snake_]
      //
      (const raw::UnionMember& element) {
        if (element.maybe_used == nullptr)
          return;
        linter.CheckCase("union members", element.maybe_used->identifier, case_check, case_type);
        linter.CheckRepeatedName("union member", element.maybe_used->identifier);
      });
  // clang-format off
  callbacks_.OnTypeConstructorOld(
      [& linter = *this,
       string_bounds_check = DefineCheck("string-bounds-not-specified",
                                         "Specify bounds for string"),
       vector_bounds_check = DefineCheck("vector-bounds-not-specified",
                                         "Specify bounds for vector")]
      //
      (const raw::TypeConstructorOld& element) {
        if (element.identifier->components.size() != 1) {
          return;
        }
        auto type = to_string(element.identifier->components[0]);
        if (!linter.in_const_declaration_) {
          if (type == "string" && element.maybe_size == nullptr) {
            linter.AddFinding(element.identifier, string_bounds_check);
          }
          if (type == "vector" && element.maybe_size == nullptr) {
            linter.AddFinding(element.identifier, vector_bounds_check);
          }
        }
      });
  // clang-format on
}

}  // namespace linter
}  // namespace fidl
