// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "verilog/analysis/symbol_table.h"

#include <algorithm>
#include <functional>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "common/text/symbol.h"
#include "common/text/tree_utils.h"
#include "common/util/file_util.h"
#include "common/util/logging.h"
#include "common/util/range.h"
#include "common/util/tree_operations.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "verilog/analysis/verilog_project.h"

namespace verilog {

// Directly test some SymbolTable internals.
class SymbolTable::Tester : public SymbolTable {
 public:
  explicit Tester(VerilogProject* project) : SymbolTable(project) {}

  using SymbolTable::MutableRoot;
};

namespace {

using testing::ElementsAreArray;
using testing::HasSubstr;
using verible::file::Basename;
using verible::file::CreateDir;
using verible::file::JoinPath;
using verible::file::testing::ScopedTestFile;

// An in-memory source file that doesn't require file-system access,
// nor create temporary files.
using TestVerilogSourceFile = InMemoryVerilogSourceFile;

struct ScopePathPrinter {
  const SymbolTableNode& node;
};

static std::ostream& operator<<(std::ostream& stream,
                                const ScopePathPrinter& p) {
  return SymbolTableNodeFullPath(stream, p.node);
}

// Assert that map/set element exists at 'key', and assigns it to 'dest'
// 'key' must be printable for failure diagnostic message.
// Defined as a macro for meaningful line numbers on failure.
#define ASSIGN_MUST_FIND(dest, map, key)                 \
  const auto found_##dest(map.find(key)); /* iterator */ \
  ASSERT_NE(found_##dest, map.end())                     \
      << "No element at \"" << key << "\" in " #map;     \
  const auto& dest ABSL_ATTRIBUTE_UNUSED(                \
      found_##dest->second); /* mapped_type */

// Assert that container is not empty, and reference its first element.
// Works on any container type with .begin().
// Defined as a macro for meaningful line numbers on failure.
#define ASSIGN_MUST_HAVE_FIRST_ELEMENT(dest, container) \
  ASSERT_FALSE(container.empty());                      \
  const auto& dest(*container.begin());

// Assert that container has exactly one-element, and reference it.
// Works on any container with .size() and .begin().
// Defined as a macro for meaningful line numbers on failure.
#define ASSIGN_MUST_HAVE_UNIQUE(dest, container) \
  ASSERT_EQ(container.size(), 1);                \
  const auto& dest(*container.begin());

// Shorthand for asserting that a symbol table lookup from
// (const SymbolTableNode& scope) using (absl::string_view key) must succeed,
// and is captured as (const SymbolTableNode& dest).
// Most of the time, the tester is not interested in the found_* iterator.
// This also defines 'dest##_info' as the SymbolInfo value attached to the
// 'dest' SymbolTableNode. Defined as a macro so that failure gives meaningful
// line numbers, and this allows ASSERT_NE to early exit.
#define MUST_ASSIGN_LOOKUP_SYMBOL(dest, scope, key)                       \
  const auto found_##dest = (scope).Find(key);                            \
  ASSERT_NE(found_##dest, (scope).end())                                  \
      << "No symbol at \"" << key << "\" in " << ScopePathPrinter{scope}; \
  EXPECT_EQ(found_##dest->first, key);                                    \
  const SymbolTableNode& dest(found_##dest->second);                      \
  const SymbolInfo& dest##_info ABSL_ATTRIBUTE_UNUSED(dest.Value())

// For SymbolInfo::references_map_view_type only: Assert that there is exactly
// one element at 'key' in 'map' and assign it to 'dest' (DependentReferences).
// 'map' should come from SymbolInfo::LocalReferencesMapViewForTesting().
#define ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dest, map, key)                 \
  ASSIGN_MUST_FIND(dest##_candidates, map, key); /* set of candidates */ \
  ASSIGN_MUST_HAVE_UNIQUE(dest, dest##_candidates);

// Expect sequence of statuses to be empty, or print first (non-ok) status.
#define EXPECT_EMPTY_STATUSES(diagnostics)                             \
  EXPECT_EQ(diagnostics.size(), 0) << "First unexpected diagnostic:\n" \
                                   << diagnostics.front().message()

TEST(SymbolMetaTypePrintTest, Print) {
  std::ostringstream stream;
  stream << SymbolMetaType::kClass;
  EXPECT_EQ(stream.str(), "class");
}

TEST(SymbolTableNodeFullPathTest, Print) {
  typedef SymbolTableNode::key_value_type KV;
  const SymbolTableNode root(
      SymbolInfo{},
      KV("AA", SymbolTableNode(SymbolInfo{}, KV("BB", SymbolTableNode{}))));
  {
    std::ostringstream stream;
    SymbolTableNodeFullPath(stream, root);
    EXPECT_EQ(stream.str(), "$root");
  }
  {
    std::ostringstream stream;
    SymbolTableNodeFullPath(stream, root.begin()->second);
    EXPECT_EQ(stream.str(), "$root::AA");
  }
  {
    std::ostringstream stream;
    SymbolTableNodeFullPath(stream, root.begin()->second.begin()->second);
    EXPECT_EQ(stream.str(), "$root::AA::BB");
  }
}

TEST(ReferenceComponentTest, MatchesMetatypeTest) {
  {  // kUnspecified matches all metatypes
    const ReferenceComponent component{
        .identifier = "",
        .ref_type = ReferenceType::kUnqualified,
        .required_metatype = SymbolMetaType::kUnspecified};
    for (const auto& other :
         {SymbolMetaType::kUnspecified, SymbolMetaType::kParameter,
          SymbolMetaType::kFunction, SymbolMetaType::kTask}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_TRUE(status.ok()) << status.message();
    }
  }
  {  // kCallable matches only kFunction and kTask
    const ReferenceComponent component{
        .identifier = "",
        .ref_type = ReferenceType::kUnqualified,
        .required_metatype = SymbolMetaType::kCallable};
    for (const auto& other :
         {SymbolMetaType::kFunction, SymbolMetaType::kTask}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_TRUE(status.ok()) << status.message();
    }
    for (const auto& other : {SymbolMetaType::kModule, SymbolMetaType::kPackage,
                              SymbolMetaType::kClass}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_FALSE(status.ok())
          << component.required_metatype << " vs. " << other;
    }
  }
  {  // kClass matches only kClass and kTypeAlias
    const ReferenceComponent component{
        .identifier = "",
        .ref_type = ReferenceType::kUnqualified,
        .required_metatype = SymbolMetaType::kClass};
    for (const auto& other :
         {SymbolMetaType::kClass, SymbolMetaType::kTypeAlias}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_TRUE(status.ok()) << status.message();
    }
    for (const auto& other :
         {SymbolMetaType::kModule, SymbolMetaType::kPackage,
          SymbolMetaType::kFunction, SymbolMetaType::kTask}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_FALSE(status.ok())
          << component.required_metatype << " vs. " << other;
    }
  }
  {  // all other types must be matched exactly
    const ReferenceComponent component{
        .identifier = "",
        .ref_type = ReferenceType::kUnqualified,
        .required_metatype = SymbolMetaType::kFunction};

    for (const auto& other :
         {SymbolMetaType::kUnspecified, SymbolMetaType::kParameter,
          SymbolMetaType::kModule, SymbolMetaType::kTask,
          SymbolMetaType::kClass}) {
      const auto status = component.MatchesMetatype(other);
      EXPECT_FALSE(status.ok())
          << component.required_metatype << " vs. " << other;
    }
  }
}

TEST(ReferenceNodeFullPathTest, Print) {
  typedef ReferenceComponentNode Node;
  typedef ReferenceComponent Data;
  const Node root(
      Data{.identifier = "xx",
           .ref_type = ReferenceType::kUnqualified,
           .required_metatype = SymbolMetaType::kClass},
      Node(Data{.identifier = "yy", .ref_type = ReferenceType::kDirectMember},
           Node(Data{.identifier = "zz",
                     .ref_type = ReferenceType::kMemberOfTypeOfParent})));
  {
    std::ostringstream stream;
    ReferenceNodeFullPath(stream, root);
    EXPECT_EQ(stream.str(), "@xx[class]");
  }
  {
    std::ostringstream stream;
    ReferenceNodeFullPath(stream, root.Children().front());
    EXPECT_EQ(stream.str(), "@xx[class]::yy");
  }
  {
    std::ostringstream stream;
    ReferenceNodeFullPath(stream, root.Children().front().Children().front());
    EXPECT_EQ(stream.str(), "@xx[class]::yy.zz");
  }
}

TEST(DependentReferencesTest, PrintEmpty) {
  DependentReferences dep_refs;
  std::ostringstream stream;
  stream << dep_refs;
  EXPECT_EQ(stream.str(), "(empty-ref)");
}

TEST(DependentReferencesTest, PrintOnlyRootNodeUnresolved) {
  const DependentReferences dep_refs{std::make_unique<ReferenceComponentNode>(
      ReferenceComponent{.identifier = "foo",
                         .ref_type = ReferenceType::kUnqualified,
                         .required_metatype = SymbolMetaType::kUnspecified,
                         .resolved_symbol = nullptr})};
  std::ostringstream stream;
  stream << dep_refs;
  EXPECT_EQ(stream.str(), "{ (@foo -> <unresolved>) }");
}

TEST(DependentReferencesTest, PrintNonRootResolved) {
  // Synthesize a symbol table.
  typedef SymbolTableNode::key_value_type KV;
  SymbolTableNode root(
      SymbolInfo{SymbolMetaType::kRoot},
      KV{"p_pkg",
         SymbolTableNode(SymbolInfo{SymbolMetaType::kPackage},
                         KV{"c_class", SymbolTableNode(SymbolInfo{
                                           SymbolMetaType::kClass})})});

  // Bookmark symbol table nodes.
  MUST_ASSIGN_LOOKUP_SYMBOL(p_pkg, root, "p_pkg");
  MUST_ASSIGN_LOOKUP_SYMBOL(c_class, p_pkg, "c_class");

  // Construct references already resolved to above nodes.
  const DependentReferences dep_refs{std::make_unique<ReferenceComponentNode>(
      ReferenceComponent{.identifier = "p_pkg",
                         .ref_type = ReferenceType::kUnqualified,
                         .required_metatype = SymbolMetaType::kPackage,
                         .resolved_symbol = &p_pkg},
      ReferenceComponentNode(
          ReferenceComponent{.identifier = "c_class",
                             .ref_type = ReferenceType::kDirectMember,
                             .required_metatype = SymbolMetaType::kClass,
                             .resolved_symbol = &c_class}))};

  // Print and compare.
  std::ostringstream stream;
  stream << dep_refs;
  EXPECT_EQ(stream.str(),
            R"({ (@p_pkg[package] -> $root::p_pkg)
  { (::c_class[class] -> $root::p_pkg::c_class) }
})");
}

TEST(SymbolTablePrintTest, PrintClass) {
  TestVerilogSourceFile src("foobar.sv",
                            "module ss;\n"
                            "endmodule\n"
                            "module tt;\n"
                            "  ss qq();\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok());
  SymbolTable symbol_table(nullptr);
  EXPECT_EQ(symbol_table.Project(), nullptr);

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  {
    std::ostringstream stream;
    symbol_table.PrintSymbolDefinitions(stream);
    EXPECT_EQ(stream.str(), R"({ (
    metatype: <root>
)
  ss: { (
      metatype: module
      file: foobar.sv
  ) }
  tt: { (
      metatype: module
      file: foobar.sv
  )
    qq: { (
        metatype: data/net/var/instance
        file: foobar.sv
        type-info { source: "ss", type ref: { (@ss -> <unresolved>) } }
    ) }
  }
})");
  }
  {
    std::ostringstream stream;
    symbol_table.PrintSymbolReferences(stream);
    EXPECT_EQ(stream.str(), R"({ (refs: )
  ss: { (refs: ) }
  tt: { (refs:
      { (@ss -> <unresolved>) }
      { (@qq[data/net/var/instance] -> $root::tt::qq) }
      )
    qq: { (refs: ) }
  }
})");
  }

  {  // Resolve symbols.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }

  {  // <unresolved> should now become "$root::ss"
    std::ostringstream stream;
    symbol_table.PrintSymbolDefinitions(stream);
    EXPECT_EQ(stream.str(), R"({ (
    metatype: <root>
)
  ss: { (
      metatype: module
      file: foobar.sv
  ) }
  tt: { (
      metatype: module
      file: foobar.sv
  )
    qq: { (
        metatype: data/net/var/instance
        file: foobar.sv
        type-info { source: "ss", type ref: { (@ss -> $root::ss) } }
    ) }
  }
})");
  }
  {  // <unresolved> should now become "$root::ss"
    std::ostringstream stream;
    symbol_table.PrintSymbolReferences(stream);
    EXPECT_EQ(stream.str(), R"({ (refs: )
  ss: { (refs: ) }
  tt: { (refs:
      { (@ss -> $root::ss) }
      { (@qq[data/net/var/instance] -> $root::tt::qq) }
      )
    qq: { (refs: ) }
  }
})");
  }
}

TEST(BuildSymbolTableTest, IntegrityCheckResolvedSymbol) {
  const auto test_func = []() {
    SymbolTable::Tester symbol_table_1(nullptr), symbol_table_2(nullptr);
    SymbolTableNode& root1(symbol_table_1.MutableRoot());
    SymbolTableNode& root2(symbol_table_2.MutableRoot());
    // Deliberately point from one symbol table to the other.
    // To avoid an use-after-free AddressSanitizer error,
    // mind the destruction ordering here:
    // symbol_table1 will outlive symbol_table_2, so give symbol_table_2 a
    // pointer to symbol_table_1.
    root2.Value().local_references_to_bind.push_back(DependentReferences{
        std::make_unique<ReferenceComponentNode>(ReferenceComponent{
            .identifier = "foo",
            .ref_type = ReferenceType::kUnqualified,
            .required_metatype = SymbolMetaType::kUnspecified,
            .resolved_symbol = &root1})});
    // CheckIntegrity() will fail on destruction of symbol_table_2.
  };
  EXPECT_DEATH(test_func(),
               "Resolved symbols must point to a node in the same SymbolTable");
}

TEST(BuildSymbolTableTest, IntegrityCheckDeclaredType) {
  const auto test_func = []() {
    SymbolTable::Tester symbol_table_1(nullptr), symbol_table_2(nullptr);
    SymbolTableNode& root1(symbol_table_1.MutableRoot());
    SymbolTableNode& root2(symbol_table_2.MutableRoot());
    // Deliberately point from one symbol table to the other.
    // To avoid an use-after-free AddressSanitizer error,
    // mind the destruction ordering here:
    // symbol_table1 will outlive symbol_table_2, so give symbol_table_2 a
    // pointer to symbol_table_1.
    root1.Value().local_references_to_bind.push_back(DependentReferences{
        std::make_unique<ReferenceComponentNode>(ReferenceComponent{
            .identifier = "foo",
            .ref_type = ReferenceType::kUnqualified,
            .required_metatype = SymbolMetaType::kUnspecified,
            .resolved_symbol = &root1})});
    root2.Value().declared_type.user_defined_type =
        root1.Value().local_references_to_bind.front().components.get();
    // CheckIntegrity() will fail on destruction of symbol_table_2.
  };
  EXPECT_DEATH(test_func(),
               "Resolved symbols must point to a node in the same SymbolTable");
}

TEST(BuildSymbolTableTest, InvalidSyntax) {
  constexpr absl::string_view invalid_codes[] = {
      "module;\nendmodule\n",
  };
  for (const auto& code : invalid_codes) {
    TestVerilogSourceFile src("foobar.sv", code);
    const auto status = src.Parse();
    EXPECT_FALSE(status.ok());
    SymbolTable symbol_table(nullptr);
    EXPECT_EQ(symbol_table.Project(), nullptr);

    {  // Attempt to build symbol table after parse failure.
      const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

      EXPECT_TRUE(symbol_table.Root().Children().empty());
      EXPECT_EMPTY_STATUSES(build_diagnostics);
    }
    {  // Attempt to resolve empty symbol table and references.
      std::vector<absl::Status> resolve_diagnostics;
      symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
      EXPECT_EMPTY_STATUSES(resolve_diagnostics);
    }
  }
}

TEST(BuildSymbolTableTest, AvoidCrashFromFuzzer) {
  // All that matters is that these test cases do not trigger crashes.
  constexpr absl::string_view codes[] = {
      // some of these test cases come from fuzz testing
      // and may contain syntax errors
      "`e(C*C);\n",              // expect two distinct reference trees
      "`e(C::D * C.m + 12);\n",  // expect two reference trees
      "n#7;\n",
      "c#1;;=P;\n",
  };
  for (const auto& code : codes) {
    TestVerilogSourceFile src("foobar.sv", code);
    const auto status = src.Parse();  // don't care if code is valid or not
    SymbolTable symbol_table(nullptr);
    EXPECT_EQ(symbol_table.Project(), nullptr);

    {  // Attempt to build symbol table.
      const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
      // don't care about diagnostics
    }
    {  // Attempt to resolve empty symbol table and references.
      std::vector<absl::Status> resolve_diagnostics;
      symbol_table.Resolve(&resolve_diagnostics);
      // don't care about diagnostics
    }
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationSingleEmpty) {
  TestVerilogSourceFile src("foobar.sv", "module m;\nendmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationLocalNetsVariables) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m;\n"
                            "  wire w1, w2;\n"
                            "  logic l1, l2;\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  static constexpr absl::string_view members[] = {"w1", "w2", "l1", "l2"};
  for (const auto& member : members) {
    MUST_ASSIGN_LOOKUP_SYMBOL(member_node, module_node, member);
    EXPECT_EQ(member_node_info.metatype,
              SymbolMetaType::kDataNetVariableInstance);
    EXPECT_EQ(member_node_info.declared_type.user_defined_type,
              nullptr);  // types are primitive
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationLocalDuplicateNets) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m;\n"
                            "  wire y1;\n"
                            "  logic y1;\n"  // y1 already declared
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  ASSIGN_MUST_HAVE_UNIQUE(err_status, build_diagnostics);
  EXPECT_EQ(err_status.code(), absl::StatusCode::kAlreadyExists);
  EXPECT_THAT(err_status.message(),
              HasSubstr("\"y1\" is already defined in the $root::m scope"));

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationConditionalGenerateAnonymous) {
  constexpr absl::string_view source_variants[] = {
      // with begin/end
      "module m;\n"
      "  if (1) begin\n"
      "    wire x;\n"
      "  end else if (2) begin\n"
      "    wire y;\n"
      "  end else begin\n"
      "    wire z;\n"
      "  end\n"
      "endmodule\n",
      // without begin/end
      "module m;\n"
      "  if (1)\n"
      "    wire x;\n"
      "  else if (2)\n"
      "    wire y;\n"
      "  else\n"
      "    wire z;\n"
      "endmodule\n",
  };
  for (const auto& code : source_variants) {
    TestVerilogSourceFile src("foobar.sv", code);
    const auto status = src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
    SymbolTable symbol_table(nullptr);
    const SymbolTableNode& root_symbol(symbol_table.Root());

    const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
    EXPECT_EMPTY_STATUSES(build_diagnostics);

    MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
    EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
    EXPECT_EQ(module_node_info.file_origin, &src);
    EXPECT_EQ(module_node_info.declared_type.syntax_origin,
              nullptr);  // there is no module meta-type

    ASSERT_EQ(module_node.Children().size(), 3);
    auto iter = module_node.Children().begin();
    {
      const SymbolTableNode& gen_block(iter->second);  // anonymous "...-0"
      const SymbolInfo& gen_block_info(gen_block.Value());
      EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
      MUST_ASSIGN_LOOKUP_SYMBOL(wire_x, gen_block, "x");
      EXPECT_EQ(wire_x_info.metatype, SymbolMetaType::kDataNetVariableInstance);
      ++iter;
    }
    {
      const SymbolTableNode& gen_block(iter->second);  // anonymous "...-1"
      const SymbolInfo& gen_block_info(gen_block.Value());
      EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
      MUST_ASSIGN_LOOKUP_SYMBOL(wire_y, gen_block, "y");
      EXPECT_EQ(wire_y_info.metatype, SymbolMetaType::kDataNetVariableInstance);
      ++iter;
    }
    {
      const SymbolTableNode& gen_block(iter->second);  // anonymous "...-2"
      const SymbolInfo& gen_block_info(gen_block.Value());
      EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
      MUST_ASSIGN_LOOKUP_SYMBOL(wire_z, gen_block, "z");
      EXPECT_EQ(wire_z_info.metatype, SymbolMetaType::kDataNetVariableInstance);
      ++iter;
    }

    {
      std::vector<absl::Status> resolve_diagnostics;
      symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
      EXPECT_EMPTY_STATUSES(resolve_diagnostics);
    }
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationConditionalGenerateLabeled) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m;\n"
                            "  if (1) begin : cc\n"
                            "    wire x;\n"
                            "  end else if (2) begin : bb\n"
                            "    wire y;\n"
                            "  end else begin : aa\n"
                            "    wire z;\n"
                            "  end\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  ASSERT_EQ(module_node.Children().size(), 3);
  {
    MUST_ASSIGN_LOOKUP_SYMBOL(gen_block, module_node, "aa");
    EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
    MUST_ASSIGN_LOOKUP_SYMBOL(wire_z, gen_block, "z");
    EXPECT_EQ(wire_z_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  }
  {
    MUST_ASSIGN_LOOKUP_SYMBOL(gen_block, module_node, "bb");
    EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
    MUST_ASSIGN_LOOKUP_SYMBOL(wire_y, gen_block, "y");
    EXPECT_EQ(wire_y_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  }
  {
    MUST_ASSIGN_LOOKUP_SYMBOL(gen_block, module_node, "cc");
    EXPECT_EQ(gen_block_info.metatype, SymbolMetaType::kGenerate);
    MUST_ASSIGN_LOOKUP_SYMBOL(wire_x, gen_block, "x");
    EXPECT_EQ(wire_x_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationWithPorts) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m (\n"
                            "  input wire clk,\n"
                            "  output reg q\n"
                            ");\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  static constexpr absl::string_view members[] = {"clk", "q"};
  for (const auto& member : members) {
    MUST_ASSIGN_LOOKUP_SYMBOL(member_node, module_node, member);
    EXPECT_EQ(member_node_info.metatype,
              SymbolMetaType::kDataNetVariableInstance);
    EXPECT_EQ(member_node_info.declared_type.user_defined_type,
              nullptr);  // types are primitive
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationMultiple) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m1;\nendmodule\n"
                            "module m2;\nendmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  const absl::string_view expected_modules[] = {"m1", "m2"};
  for (const auto& expected_module : expected_modules) {
    MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, expected_module);
    EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
    EXPECT_EQ(module_node_info.file_origin, &src);
    EXPECT_EQ(module_node_info.declared_type.syntax_origin,
              nullptr);  // there is no module meta-type
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationDuplicate) {
  TestVerilogSourceFile src("foobar.sv",
                            "module mm;\nendmodule\n"
                            "module mm;\nendmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "mm");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
  EXPECT_EQ(err.code(), absl::StatusCode::kAlreadyExists);
  EXPECT_THAT(err.message(),
              HasSubstr("\"mm\" is already defined in the $root scope"));

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationNested) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m_outer;\n"
                            "  module m_inner;\n"
                            "  endmodule\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(outer_module_node, root_symbol, "m_outer");
  {
    EXPECT_EQ(outer_module_node_info.metatype, SymbolMetaType::kModule);
    EXPECT_EQ(outer_module_node_info.file_origin, &src);
    EXPECT_EQ(outer_module_node_info.declared_type.syntax_origin,
              nullptr);  // there is no module meta-type
  }
  {
    MUST_ASSIGN_LOOKUP_SYMBOL(inner_module_node, outer_module_node, "m_inner");
    EXPECT_EQ(inner_module_node_info.metatype, SymbolMetaType::kModule);
    EXPECT_EQ(inner_module_node_info.file_origin, &src);
    EXPECT_EQ(inner_module_node_info.declared_type.syntax_origin,
              nullptr);  // there is no module meta-type
  }
  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationNestedDuplicate) {
  TestVerilogSourceFile src("foobar.sv",
                            "module outer;\n"
                            "  module mm;\nendmodule\n"
                            "  module mm;\nendmodule\n"  // dupe
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "outer");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);

  ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
  EXPECT_EQ(err.code(), absl::StatusCode::kAlreadyExists);
  EXPECT_THAT(err.message(),
              HasSubstr("\"mm\" is already defined in the $root::outer scope"));
  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ModuleInstance) {
  // The following code variants should yield the same symbol table results:
  static constexpr absl::string_view source_variants[] = {
      // pp defined earlier in file
      "module pp;\n"
      "endmodule\n"
      "module qq;\n"
      "  pp rr();\n"  // instance
      "endmodule\n",
      // pp defined later in file
      "module qq;\n"
      "  pp rr();\n"  // instance
      "endmodule\n"
      "module pp;\n"
      "endmodule\n",
  };
  for (const auto& code : source_variants) {
    VLOG(1) << "code:\n" << code;
    TestVerilogSourceFile src("foobar.sv", code);
    const auto status = src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
    SymbolTable symbol_table(nullptr);
    const SymbolTableNode& root_symbol(symbol_table.Root());

    const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
    EXPECT_EMPTY_STATUSES(build_diagnostics);

    // Goal: resolve the reference of "pp" to this definition node.
    MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

    // Inspect inside the "qq" module definition.
    MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

    // "rr" is an instance of type "pp"
    MUST_ASSIGN_LOOKUP_SYMBOL(rr, qq, "rr");

    {
      EXPECT_EQ(qq_info.file_origin, &src);
      ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
      const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
        const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "pp");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "rr" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(rr_self_ref, ref_map, "rr");
        EXPECT_TRUE(is_leaf(*rr_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(rr_self_ref->components->Value().resolved_symbol, &rr);
      }
    }

    EXPECT_TRUE(rr_info.local_references_to_bind.empty());
    EXPECT_NE(rr_info.declared_type.user_defined_type, nullptr);
    {
      const ReferenceComponent& pp_type(
          rr_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(pp_type.identifier, "pp");
      EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
    }
    EXPECT_EQ(rr_info.file_origin, &src);

    // Resolve symbols.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Verify that typeof(rr) successfully resolved to module pp.
    EXPECT_EQ(rr_info.declared_type.user_defined_type->Value().resolved_symbol,
              &pp);
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceUndefined) {
  TestVerilogSourceFile src("foobar.sv",
                            "module qq;\n"
                            "  pp rr();\n"  // instance, pp undefined
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Inspect inside the "qq" module definition.
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");
  {
    EXPECT_EQ(qq_info.file_origin, &src);
    // There is only one reference to the "pp" module type.
    ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
    const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
    ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
    {  // verify that a reference to "pp" was established
      const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "pp");
      EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                      src.GetTextStructure()->Contents()));
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
  }

  // "rr" is an instance of type "pp" (which is undefined)
  MUST_ASSIGN_LOOKUP_SYMBOL(rr, qq, "rr");
  EXPECT_TRUE(rr_info.local_references_to_bind.empty());
  EXPECT_NE(rr_info.declared_type.user_defined_type, nullptr);
  {
    const ReferenceComponent& pp_type(
        rr_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(pp_type.identifier, "pp");
    EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
  }
  EXPECT_EQ(rr_info.file_origin, &src);

  {
    // Resolve symbols.  Expect one unresolved symbol.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(err_status, resolve_diagnostics);
    EXPECT_EQ(err_status.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(err_status.message(),
                HasSubstr("Unable to resolve symbol \"pp\""));
    // Verify that typeof(rr) failed to resolve "pp".
    EXPECT_EQ(rr_info.declared_type.user_defined_type->Value().resolved_symbol,
              nullptr);
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceTwoInSameDecl) {
  static constexpr absl::string_view source_variants[] = {
      // The following all yield equivalent symbol tables bindings.
      "module pp;\n"
      "endmodule\n"
      "module qq;\n"
      "  pp r1(), r2();\n"  // instances
      "endmodule\n",
      "module qq;\n"
      "  pp r1(), r2();\n"  // instances
      "endmodule\n"
      "module pp;\n"
      "endmodule\n",
      // swap r1, r2 order
      "module pp;\n"
      "endmodule\n"
      "module qq;\n"
      "  pp r2(), r1();\n"  // instances
      "endmodule\n",
      "module qq;\n"
      "  pp r2(), r1();\n"  // instances
      "endmodule\n"
      "module pp;\n"
      "endmodule\n",
  };
  for (const auto& code : source_variants) {
    TestVerilogSourceFile src("foobar.sv", code);
    const auto status = src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
    SymbolTable symbol_table(nullptr);
    const SymbolTableNode& root_symbol(symbol_table.Root());

    const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
    EXPECT_EMPTY_STATUSES(build_diagnostics);

    MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

    // Inspect inside the "qq" module definition.
    MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");
    {
      EXPECT_EQ(qq_info.file_origin, &src);
      // There is only one type reference of interest, the "pp" module type.
      // The other two are instance self-references.
      ASSERT_EQ(qq_info.local_references_to_bind.size(), 3);
      const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
      const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "pp");
      EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                      src.GetTextStructure()->Contents()));
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }

    // "r1" and "r2" are both instances of type "pp"
    static constexpr absl::string_view pp_instances[] = {"r1", "r2"};
    for (const auto& pp_inst : pp_instances) {
      MUST_ASSIGN_LOOKUP_SYMBOL(rr, qq, pp_inst);
      EXPECT_TRUE(rr_info.local_references_to_bind.empty());
      EXPECT_NE(rr_info.declared_type.user_defined_type, nullptr);
      {
        const ReferenceComponent& pp_type(
            rr_info.declared_type.user_defined_type->Value());
        EXPECT_EQ(pp_type.identifier, "pp");
        EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
        EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
      }
      EXPECT_EQ(rr_info.file_origin, &src);
    }

    {
      std::vector<absl::Status> resolve_diagnostics;
      symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
      EXPECT_EMPTY_STATUSES(resolve_diagnostics);

      for (const auto& pp_inst : pp_instances) {
        MUST_ASSIGN_LOOKUP_SYMBOL(rr, qq, pp_inst);
        EXPECT_TRUE(rr_info.local_references_to_bind.empty());
        // Verify that typeof(r1,r2) successfully resolved to module pp.
        EXPECT_EQ(
            rr_info.declared_type.user_defined_type->Value().resolved_symbol,
            &pp);
      }
    }
  }
}

TEST(BuildSymbolTableTest, ModuleInstancePositionalPortConnection) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m (\n"
                            "  input wire clk,\n"
                            "  output reg q\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  wire c, d;\n"
                            "  m m_inst(c, d);"
                            // one type reference, two net references
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_node, m_node, "clk");
  EXPECT_EQ(clk_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(q_node, m_node, "q");
  EXPECT_EQ(q_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(q_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");

  // Inspect local references to wires "c" and "d".
  ASSERT_EQ(rr_node_info.local_references_to_bind.size(), 4);
  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(c_ref, ref_map, "c");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(d_ref, ref_map, "d");
  EXPECT_EQ(c_ref->LastLeaf()->Value().identifier, "c");
  EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, nullptr);
  EXPECT_EQ(d_ref->LastLeaf()->Value().identifier, "d");
  EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, nullptr);

  // Get the local symbol definitions for wires "c" and "d".
  MUST_ASSIGN_LOOKUP_SYMBOL(c_node, rr_node, "c");
  MUST_ASSIGN_LOOKUP_SYMBOL(d_node, rr_node, "d");

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect to resolve local references to wires "c" and "d".
    EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, &c_node);
    EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, &d_node);
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedPortConnection) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m (\n"
                            "  input wire clk,\n"
                            "  output reg q\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  wire c, d;\n"
                            "  m m_inst(.clk(c), .q(d));"
                            // one type reference, two local net references
                            // two named port references
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_node, m_node, "clk");
  EXPECT_EQ(clk_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(q_node, m_node, "q");
  EXPECT_EQ(q_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(q_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");

  // Inspect local references to wires "c" and "d".
  ASSERT_EQ(rr_node_info.local_references_to_bind.size(), 4);
  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(c_ref, ref_map, "c");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(d_ref, ref_map, "d");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_inst_ref, ref_map, "m_inst");
  EXPECT_EQ(c_ref->LastLeaf()->Value().identifier, "c");
  EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, nullptr);
  EXPECT_EQ(d_ref->LastLeaf()->Value().identifier, "d");
  EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, nullptr);

  const ReferenceComponentNode& m_inst_ref_root(*m_inst_ref->components);
  ASSERT_EQ(m_inst_ref_root.Children().size(), 2);
  const ReferenceComponentMap port_refs(
      ReferenceComponentNodeMapView(m_inst_ref_root));

  ASSIGN_MUST_FIND(clk_ref, port_refs, "clk");
  const ReferenceComponent& clk_ref_comp(clk_ref->Value());
  EXPECT_EQ(clk_ref_comp.identifier, "clk");
  EXPECT_EQ(clk_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(clk_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(q_ref, port_refs, "q");
  const ReferenceComponent& q_ref_comp(q_ref->Value());
  EXPECT_EQ(q_ref_comp.identifier, "q");
  EXPECT_EQ(q_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(q_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(q_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  // Get the local symbol definitions for wires "c" and "d".
  MUST_ASSIGN_LOOKUP_SYMBOL(c_node, rr_node, "c");
  MUST_ASSIGN_LOOKUP_SYMBOL(d_node, rr_node, "d");

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect to resolve local references to wires c and d
    EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, &c_node);
    EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, &d_node);

    // Expect to resolved named port references to "clk" and "q".
    EXPECT_EQ(clk_ref_comp.resolved_symbol, &clk_node);
    EXPECT_EQ(q_ref_comp.resolved_symbol, &q_node);
  }
}

TEST(BuildSymbolTableTest,
     ModuleInstanceNamedPortConnectionResolveLocallyOnly) {
  // Similar to ModuleInstanceNamedPortConnection, but will not resolve
  // non-local references.
  TestVerilogSourceFile src("foobar.sv",
                            "module m (\n"
                            "  input wire clk,\n"
                            "  output reg q\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  wire c, d;\n"
                            "  m m_inst(.clk(c), .q(d));"
                            // one type reference, two local net references
                            // two named port references
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_node, m_node, "clk");
  EXPECT_EQ(clk_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(q_node, m_node, "q");
  EXPECT_EQ(q_node_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(q_node_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");

  // Inspect local references to wires "c" and "d".
  ASSERT_EQ(rr_node_info.local_references_to_bind.size(), 4);
  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(c_ref, ref_map, "c");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(d_ref, ref_map, "d");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_inst_ref, ref_map, "m_inst");
  // Initially not resolved, but will be resolved below.
  EXPECT_EQ(c_ref->LastLeaf()->Value().identifier, "c");
  EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, nullptr);
  EXPECT_EQ(d_ref->LastLeaf()->Value().identifier, "d");
  EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, nullptr);

  const ReferenceComponentNode& m_inst_ref_root(*m_inst_ref->components);
  ASSERT_EQ(m_inst_ref_root.Children().size(), 2);
  const ReferenceComponentMap port_refs(
      ReferenceComponentNodeMapView(m_inst_ref_root));

  ASSIGN_MUST_FIND(clk_ref, port_refs, "clk");
  const ReferenceComponent& clk_ref_comp(clk_ref->Value());
  EXPECT_EQ(clk_ref_comp.identifier, "clk");
  EXPECT_EQ(clk_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(clk_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  // "clk" is a non-local reference that will not even be resolved below
  EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(q_ref, port_refs, "q");
  const ReferenceComponent& q_ref_comp(q_ref->Value());
  EXPECT_EQ(q_ref_comp.identifier, "q");
  EXPECT_EQ(q_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(q_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  // "q" is a non-local reference that will not even be resolved below
  EXPECT_EQ(q_ref_comp.resolved_symbol, nullptr);

  // Get the local symbol definitions for wires "c" and "d".
  MUST_ASSIGN_LOOKUP_SYMBOL(c_node, rr_node, "c");
  MUST_ASSIGN_LOOKUP_SYMBOL(d_node, rr_node, "d");

  // Running this twice changes nothing and is safe.
  for (int i = 0; i < 2; ++i) {
    symbol_table.ResolveLocallyOnly();

    // Expect to resolve local references to wires c and d
    EXPECT_EQ(c_ref->LastLeaf()->Value().resolved_symbol, &c_node);
    EXPECT_EQ(d_ref->LastLeaf()->Value().resolved_symbol, &d_node);

    // Expect to named port references to "clk" and "q" to remain unresolved.
    EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);
    EXPECT_EQ(q_ref_comp.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, ModuleInstancePositionalParameterAssignment) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int N = 1\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  m #(3) m_inst();"
                            // one type reference to "m"
                            // one instance self-reference
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, m_node, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");
  MUST_ASSIGN_LOOKUP_SYMBOL(m_inst_node, rr_node, "m_inst");

  // Inspect local references to "m" and "m_inst".
  ASSERT_EQ(rr_node_info.local_references_to_bind.size(), 2);
  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_ref, ref_map, "m");
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_inst_ref, ref_map, "m_inst");
  EXPECT_EQ(m_ref->LastLeaf()->Value().identifier, "m");
  EXPECT_EQ(m_ref->LastLeaf()->Value().resolved_symbol, nullptr);
  EXPECT_EQ(m_inst_ref->LastLeaf()->Value().identifier, "m_inst");
  EXPECT_EQ(m_inst_ref->LastLeaf()->Value().resolved_symbol, &m_inst_node);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect to resolve local references to "m" and "m_inst".
    EXPECT_EQ(m_ref->LastLeaf()->Value().resolved_symbol, &m_node);
    EXPECT_EQ(m_inst_ref->LastLeaf()->Value().resolved_symbol, &m_inst_node);
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedParameterAssignment) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int N = 0,\n"
                            "  int P = 1\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  m #(.N(2), .P(3)) m_inst();"
                            // one type reference, one instance self-reference
                            // two named param rereference
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, m_node, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(p_param, m_node, "P");
  EXPECT_EQ(p_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(p_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");
  MUST_ASSIGN_LOOKUP_SYMBOL(m_inst_node, rr_node, "m_inst");

  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_type_ref, ref_map, "m");

  const ReferenceComponentNode& m_type_ref_root(*m_type_ref->components);
  ASSERT_EQ(m_type_ref_root.Children().size(), 2);
  const ReferenceComponentMap param_refs(
      ReferenceComponentNodeMapView(m_type_ref_root));

  ASSIGN_MUST_FIND(n_ref, param_refs, "N");
  const ReferenceComponent& n_ref_comp(n_ref->Value());
  EXPECT_EQ(n_ref_comp.identifier, "N");
  EXPECT_EQ(n_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(n_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(p_ref, param_refs, "P");
  const ReferenceComponent& p_ref_comp(p_ref->Value());
  EXPECT_EQ(p_ref_comp.identifier, "P");
  EXPECT_EQ(p_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(p_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(p_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect ".N" and ".P" to resolve to formal parameters of "m".
    EXPECT_EQ(n_ref_comp.resolved_symbol, &n_param);
    EXPECT_EQ(p_ref_comp.resolved_symbol, &p_param);
  }
}

TEST(BuildSymbolTableTest, TimerAsModuleNameRegressionIssue917) {
  TestVerilogSourceFile src("foobar.sv",
                            "module foo;\n"
                            " timer #(.N(1)) t;\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_node, root_symbol, "foo");
  MUST_ASSIGN_LOOKUP_SYMBOL(timer_instance_node, foo_node, "t");
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedPortIsParameter) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int N = 0\n"
                            ") (\n"
                            "  input wire clk\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  m #(.clk(2)) m_inst();"
                            // error: clk is a net-port, not parameter
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, m_node, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_port, m_node, "clk");
  EXPECT_EQ(clk_port_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_port_info.declared_type.user_defined_type,
            nullptr);  // type is primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");
  MUST_ASSIGN_LOOKUP_SYMBOL(m_inst_node, rr_node, "m_inst");

  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_type_ref, ref_map, "m");

  const ReferenceComponentNode& m_type_ref_root(*m_type_ref->components);
  ASSERT_EQ(m_type_ref_root.Children().size(), 1);
  const ReferenceComponentMap param_refs(
      ReferenceComponentNodeMapView(m_type_ref_root));

  ASSIGN_MUST_FIND(clk_ref, param_refs, "clk");
  const ReferenceComponent& clk_ref_comp(clk_ref->Value());
  EXPECT_EQ(clk_ref_comp.identifier, "clk");
  EXPECT_EQ(clk_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(clk_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    // Expect ".clk" to fail to resolve.
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"clk\" to resolve to a "
                          "parameter, but found a data/net/var/instance"));
    EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);  // still unresolved
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedParameterIsPort) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int N = 0\n"
                            ") (\n"
                            "  input wire clk\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  m m_inst(.N(1));"
                            // error: N is a parameter, not net-port
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, m_node, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_param_info.declared_type.user_defined_type,
            nullptr);  // type is primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_port, m_node, "clk");
  EXPECT_EQ(clk_port_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_port_info.declared_type.user_defined_type,
            nullptr);  // type is primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");
  MUST_ASSIGN_LOOKUP_SYMBOL(m_inst_node, rr_node, "m_inst");

  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_inst_ref, ref_map, "m_inst");

  const ReferenceComponentNode& m_inst_ref_root(*m_inst_ref->components);
  ASSERT_EQ(m_inst_ref_root.Children().size(), 1);
  const ReferenceComponentMap port_refs(
      ReferenceComponentNodeMapView(m_inst_ref_root));

  ASSIGN_MUST_FIND(n_ref, port_refs, "N");
  const ReferenceComponent& n_ref_comp(n_ref->Value());
  EXPECT_EQ(n_ref_comp.identifier, "N");
  EXPECT_EQ(n_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(n_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(n_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    // Expect ".N" to fail to resolve.
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"N\" to resolve to a "
                          "data/net/var/instance, but found a parameter"));
    EXPECT_EQ(n_ref_comp.resolved_symbol, nullptr);  // still unresolved
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedPortConnectionNonexistentPort) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m (\n"
                            "  input wire clk,\n"
                            "  output reg q\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  wire c;\n"
                            "  m m_inst(.clk(c), .p(c));"
                            // one type reference, two local net references
                            // two named port references, "p" does not exist
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");

  MUST_ASSIGN_LOOKUP_SYMBOL(clk_node, m_node, "clk");

  MUST_ASSIGN_LOOKUP_SYMBOL(q_node, m_node, "q");

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");

  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_inst_ref, ref_map, "m_inst");
  ASSERT_NE(m_inst_ref, nullptr);

  const ReferenceComponentNode& m_inst_ref_root(*m_inst_ref->components);
  ASSERT_EQ(m_inst_ref_root.Children().size(), 2);
  const ReferenceComponentMap port_refs(
      ReferenceComponentNodeMapView(m_inst_ref_root));

  ASSIGN_MUST_FIND(clk_ref, port_refs, "clk");
  const ReferenceComponent& clk_ref_comp(clk_ref->Value());
  EXPECT_EQ(clk_ref_comp.identifier, "clk");
  EXPECT_EQ(clk_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(clk_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(clk_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(p_ref, port_refs, "p");
  const ReferenceComponent& p_ref_comp(p_ref->Value());
  EXPECT_EQ(p_ref_comp.identifier, "p");
  EXPECT_EQ(p_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(p_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(p_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  // Get the local symbol definitions for wire "c".
  MUST_ASSIGN_LOOKUP_SYMBOL(c_node, rr_node, "c");

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"p\" in parent scope (module) m."));

    // Expect to resolved named port reference to "clk", but not "p".
    EXPECT_EQ(clk_ref_comp.resolved_symbol, &clk_node);
    EXPECT_EQ(p_ref_comp.resolved_symbol, nullptr);  // failed to resolve
  }
}

TEST(BuildSymbolTableTest, ModuleInstanceNamedParameterNonexistentError) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int N = 0,\n"
                            "  int P = 1\n"
                            ");\n"
                            "endmodule\n"
                            "module rr;\n"
                            "  m #(.N(2), .Q(3)) m_inst();"
                            // one type reference, one instance self-reference
                            // two named param rereference (one error)
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(m_node, root_symbol, "m");
  EXPECT_EQ(m_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(m_node_info.file_origin, &src);
  EXPECT_EQ(m_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, m_node, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(p_param, m_node, "P");
  EXPECT_EQ(p_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(p_param_info.declared_type.user_defined_type,
            nullptr);  // types are primitive

  MUST_ASSIGN_LOOKUP_SYMBOL(rr_node, root_symbol, "rr");
  MUST_ASSIGN_LOOKUP_SYMBOL(m_inst_node, rr_node, "m_inst");

  const auto ref_map(rr_node_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(m_type_ref, ref_map, "m");

  const ReferenceComponentNode& m_type_ref_root(*m_type_ref->components);
  ASSERT_EQ(m_type_ref_root.Children().size(), 2);
  const ReferenceComponentMap param_refs(
      ReferenceComponentNodeMapView(m_type_ref_root));

  ASSIGN_MUST_FIND(n_ref, param_refs, "N");
  const ReferenceComponent& n_ref_comp(n_ref->Value());
  EXPECT_EQ(n_ref_comp.identifier, "N");
  EXPECT_EQ(n_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(n_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(n_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(q_ref, param_refs, "Q");
  const ReferenceComponent& q_ref_comp(q_ref->Value());
  EXPECT_EQ(q_ref_comp.identifier, "Q");
  EXPECT_EQ(q_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(q_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(q_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);

    // Expect only ".N" to resolve to formal parameters of "m".
    EXPECT_EQ(n_ref_comp.resolved_symbol, &n_param);
    EXPECT_EQ(q_ref_comp.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, OneGlobalIntParameter) {
  TestVerilogSourceFile src("foobar.sv", "localparam int mint = 1;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint_param, root_symbol, "mint");
  EXPECT_EQ(mint_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_param_info.file_origin, &src);
  ASSERT_NE(mint_param_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*mint_param_info.declared_type.syntax_origin),
      "int");

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, OneGlobalUndefinedTypeParameter) {
  TestVerilogSourceFile src("foobar.sv", "localparam foo_t gun = 1;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(gun_param, root_symbol, "gun");
  EXPECT_EQ(gun_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(gun_param_info.file_origin, &src);
  ASSERT_NE(gun_param_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*gun_param_info.declared_type.syntax_origin),
      "foo_t");

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve

    ASSIGN_MUST_HAVE_UNIQUE(err_status, resolve_diagnostics);
    EXPECT_EQ(err_status.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(err_status.message(),
                HasSubstr("Unable to resolve symbol \"foo_t\""));
    EXPECT_EQ(
        gun_param_info.declared_type.user_defined_type->Value().resolved_symbol,
        nullptr);  // not resolved
  }
}

TEST(BuildSymbolTableTest, ReferenceOneParameterExpression) {
  TestVerilogSourceFile src("foobar.sv",
                            "localparam int mint = 1;\n"
                            "localparam int tea = mint;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(tea, root_symbol, "tea");
  EXPECT_EQ(tea_info.metatype, SymbolMetaType::kParameter);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint, root_symbol, "mint");
  EXPECT_EQ(mint_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_info.file_origin, &src);
  ASSERT_NE(mint_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(*mint_info.declared_type.syntax_origin),
            "int");

  // There should be one reference: "mint" (line 2)
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ref, ref_map, "mint");
  const ReferenceComponent& ref_comp(ref->components->Value());
  EXPECT_TRUE(is_leaf(*ref->components));
  EXPECT_EQ(ref_comp.identifier, "mint");
  EXPECT_EQ(ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(ref_comp.resolved_symbol,
            nullptr);  // have not tried to resolve yet

  {  // resolve symbols
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(ref_comp.resolved_symbol, &mint);  // resolved
  }
}

TEST(BuildSymbolTableTest, OneUnresolvedReferenceInExpression) {
  TestVerilogSourceFile src("foobar.sv", "localparam int mint = spice;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint, root_symbol, "mint");
  EXPECT_EQ(mint_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_info.file_origin, &src);
  ASSERT_NE(mint_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(*mint_info.declared_type.syntax_origin),
            "int");

  // There should be one reference: "spice" (line 2)
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ref, ref_map, "spice");
  const ReferenceComponent& ref_comp(ref->components->Value());
  EXPECT_TRUE(is_leaf(*ref->components));
  EXPECT_EQ(ref_comp.identifier, "spice");
  EXPECT_EQ(ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(ref_comp.resolved_symbol,
            nullptr);  // have not tried to resolve yet

  {  // resolve symbols
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(err_status, resolve_diagnostics);
    EXPECT_EQ(err_status.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(err_status.message(),
                HasSubstr("Unable to resolve symbol \"spice\""));
    EXPECT_EQ(ref_comp.resolved_symbol, nullptr);  // still resolved
  }
}

TEST(BuildSymbolTableTest, PackageDeclarationSingle) {
  TestVerilogSourceFile src("foobar.sv", "package my_pkg;\nendpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(my_pkg, root_symbol, "my_pkg");
  EXPECT_EQ(my_pkg_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(my_pkg_info.file_origin, &src);
  EXPECT_EQ(my_pkg_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ReferenceOneParameterFromPackageToRoot) {
  TestVerilogSourceFile src("foobar.sv",
                            "localparam int mint = 1;\n"
                            "package p;\n"
                            "localparam int tea = mint;\n"  // reference
                            "endpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(p_pkg, root_symbol, "p");
  EXPECT_EQ(p_pkg_info.metatype, SymbolMetaType::kPackage);

  ASSERT_EQ(p_pkg_info.local_references_to_bind.size(), 1);
  const auto ref_map(p_pkg_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ref, ref_map, "mint");
  const ReferenceComponent& mint_ref(ref->components->Value());
  EXPECT_EQ(mint_ref.identifier, "mint");
  EXPECT_EQ(mint_ref.resolved_symbol, nullptr);  // not yet resolved

  MUST_ASSIGN_LOOKUP_SYMBOL(tea, p_pkg, "tea");  // p::tea
  EXPECT_EQ(tea_info.metatype, SymbolMetaType::kParameter);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint, root_symbol, "mint");
  EXPECT_EQ(mint_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_info.file_origin, &src);
  ASSERT_NE(mint_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(*mint_info.declared_type.syntax_origin),
            "int");

  {  // resolve symbols
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(mint_ref.resolved_symbol, &mint);  // resolved "mint"
  }
}

TEST(BuildSymbolTableTest, ReferenceOneParameterFromRootToPackage) {
  TestVerilogSourceFile src(
      "foobar.sv",
      "package p;\n"
      "localparam int mint = 1;\n"
      "endpackage\n"
      "localparam int tea = p::mint;\n"  // qualified reference
  );
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(p_pkg, root_symbol, "p");
  EXPECT_EQ(p_pkg_info.metatype, SymbolMetaType::kPackage);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  // p_mint_ref is the reference chain for "p::mint".
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(p_mint_ref, ref_map, "p");
  const ReferenceComponent& p_ref(p_mint_ref->components->Value());
  EXPECT_EQ(p_ref.identifier, "p");
  EXPECT_EQ(p_ref.resolved_symbol, nullptr);  // not yet resolved
  const ReferenceComponent& mint_ref(p_mint_ref->LastLeaf()->Value());
  EXPECT_EQ(mint_ref.identifier, "mint");
  EXPECT_EQ(mint_ref.resolved_symbol, nullptr);  // not yet resolved

  MUST_ASSIGN_LOOKUP_SYMBOL(tea, root_symbol, "tea");
  EXPECT_EQ(tea_info.metatype, SymbolMetaType::kParameter);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint, p_pkg, "mint");  // p::mint
  EXPECT_EQ(mint_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_info.file_origin, &src);
  ASSERT_NE(mint_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(*mint_info.declared_type.syntax_origin),
            "int");

  {  // resolve symbols
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(p_ref.resolved_symbol, &p_pkg);    // resolved "p"
    EXPECT_EQ(mint_ref.resolved_symbol, &mint);  // resolved "p::mint"
  }
}

TEST(BuildSymbolTableTest, ReferenceOneParameterFromRootToPackageNoSuchMember) {
  TestVerilogSourceFile src("foobar.sv",
                            "package p;\n"
                            "localparam int mint = 1;\n"
                            "endpackage\n"
                            "localparam int tea = p::zzz;\n"  // expect fail
  );
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(p_pkg, root_symbol, "p");
  EXPECT_EQ(p_pkg_info.metatype, SymbolMetaType::kPackage);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  // p_mint_ref is the reference chain for "p::mint".
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(p_mint_ref, ref_map, "p");
  const ReferenceComponent& p_ref(p_mint_ref->components->Value());
  EXPECT_EQ(p_ref.identifier, "p");
  EXPECT_EQ(p_ref.resolved_symbol, nullptr);  // not yet resolved
  const ReferenceComponent& zzz_ref(p_mint_ref->LastLeaf()->Value());
  EXPECT_EQ(zzz_ref.identifier, "zzz");
  EXPECT_EQ(zzz_ref.resolved_symbol, nullptr);  // not yet resolved

  MUST_ASSIGN_LOOKUP_SYMBOL(tea, root_symbol, "tea");
  EXPECT_EQ(tea_info.metatype, SymbolMetaType::kParameter);

  MUST_ASSIGN_LOOKUP_SYMBOL(mint, p_pkg, "mint");
  EXPECT_EQ(mint_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(mint_info.file_origin, &src);
  ASSERT_NE(mint_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(*mint_info.declared_type.syntax_origin),
            "int");

  // resolving twice should not change results
  for (int i = 0; i < 2; ++i) {  // resolve symbols
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(err_status, resolve_diagnostics);
    EXPECT_EQ(err_status.code(), absl::StatusCode::kNotFound);
    EXPECT_EQ(p_ref.resolved_symbol, &p_pkg);     // resolved "p"
    EXPECT_EQ(zzz_ref.resolved_symbol, nullptr);  // unresolved "p::zzz"
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationWithParameters) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  int W = 2,\n"
                            "  bar B = W\n"
                            ");\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_node, root_symbol, "m");
  EXPECT_EQ(module_node_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_node_info.file_origin, &src);
  EXPECT_EQ(module_node_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(w_param, module_node, "W");
  EXPECT_EQ(w_param_info.metatype, SymbolMetaType::kParameter);
  const ReferenceComponentNode* w_type_ref =
      w_param_info.declared_type.user_defined_type;
  EXPECT_EQ(w_type_ref, nullptr);  // int is primitive type

  MUST_ASSIGN_LOOKUP_SYMBOL(b_param, module_node, "B");
  EXPECT_EQ(b_param_info.metatype, SymbolMetaType::kParameter);
  const ReferenceComponentNode* b_type_ref =
      b_param_info.declared_type.user_defined_type;
  ASSERT_NE(b_type_ref, nullptr);
  const ReferenceComponent& b_type_ref_comp(b_type_ref->Value());
  EXPECT_EQ(b_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(b_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(b_type_ref_comp.identifier, "bar");

  ASSERT_EQ(module_node_info.local_references_to_bind.size(), 2);
  const auto ref_map(module_node_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(w_ref, ref_map, "W");
  const ReferenceComponent& w_ref_comp(w_ref->components->Value());
  EXPECT_EQ(w_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(w_ref_comp.identifier, "W");
  EXPECT_EQ(w_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(bar_ref, ref_map, "bar");
  const ReferenceComponent& bar_ref_comp(bar_ref->components->Value());
  EXPECT_EQ(bar_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(bar_ref_comp.identifier, "bar");
  EXPECT_EQ(bar_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    ASSIGN_MUST_HAVE_UNIQUE(error, resolve_diagnostics);
    // type reference 'bar' is unresolved
    EXPECT_EQ(error.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(error.message(), HasSubstr("Unable to resolve symbol \"bar\""));

    EXPECT_EQ(w_ref_comp.resolved_symbol, &w_param);   // resolved successfully
    EXPECT_EQ(bar_ref_comp.resolved_symbol, nullptr);  // failed to resolve
  }
}

TEST(BuildSymbolTableTest, ModuleDeclarationLocalsDependOnParameter) {
  TestVerilogSourceFile src("foobar.sv",
                            "module m #(\n"
                            "  parameter int N = 2\n"
                            ") (\n"
                            "  input logic [N-1:0] ins,\n"  // ref
                            "  output reg [0:N-1] outs\n"   // ref
                            ");\n"
                            "  wire [N][N] arr[N][N];\n"  // 4 refs
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, module_m, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  const ReferenceComponentNode* n_type_ref =
      n_param_info.declared_type.user_defined_type;
  EXPECT_EQ(n_type_ref, nullptr);  // int is primitive type

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 6);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(n_refs, ref_map, "N");
  ASSERT_EQ(n_refs.size(), 6);  // all references to "N" parameter
  for (const auto& n_ref : n_refs) {
    const ReferenceComponent& n_ref_comp(n_ref->components->Value());
    EXPECT_EQ(n_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(n_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(n_ref_comp.identifier, "N");
    EXPECT_EQ(n_ref_comp.resolved_symbol, nullptr);  // not yet resolved
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "N" resolved.
    for (const auto& n_ref : n_refs) {
      const ReferenceComponent& n_ref_comp(n_ref->components->Value());
      EXPECT_EQ(n_ref_comp.resolved_symbol, &n_param);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleSingleImplicitDeclaration) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;"
                            "assign a = 1'b0;"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(a_variable, module_m, "a");
  EXPECT_EQ(a_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* a_type_ref =
      a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(a_type_ref, nullptr);  // implicit type is primitive type
  EXPECT_TRUE(a_variable_info.declared_type.implicit);

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 1);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(a_refs, ref_map, "a");
  ASSERT_EQ(a_refs.size(), 1);  // all references to "a" parameter
  for (const auto& a_ref : a_refs) {
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, &a_variable);  // pre-resolved
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    // Resolve mustn't break anything
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "a" resolved.
    for (const auto& a_ref : a_refs) {
      const ReferenceComponent& a_ref_comp(a_ref->components->Value());
      EXPECT_EQ(a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleReferenceToImplicitDeclaration) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;"
                            "assign a = 1'b0;"
                            "assign a = 1'b1;"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(a_variable, module_m, "a");
  EXPECT_EQ(a_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* a_type_ref =
      a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(a_type_ref, nullptr);  // implicit type is primitive type
  EXPECT_TRUE(a_variable_info.declared_type.implicit);

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 2);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(a_refs, ref_map, "a");
  ASSERT_EQ(a_refs.size(), 2);  // all references to "a" parameter
  {
    const auto& a_ref = *a_refs.begin();
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, &a_variable);  // pre-resolved
  }
  {
    const auto& a_ref = *std::next(a_refs.begin());
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, nullptr);  // pre-resolved
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "a" resolved.
    for (const auto& a_ref : a_refs) {
      const ReferenceComponent& a_ref_comp(a_ref->components->Value());
      EXPECT_EQ(a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleReferenceToImplicitDeclarationInSubScope) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;"
                            " assign a = 1'b0;"
                            " module n;"
                            "  assign a = 1'b1;"
                            " endmodule;"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(a_variable, module_m, "a");
  EXPECT_EQ(a_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* a_type_ref =
      a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(a_type_ref, nullptr);  // implicit type is primitive type
  EXPECT_TRUE(a_variable_info.declared_type.implicit);

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 1);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(a_refs, ref_map, "a");
  ASSERT_EQ(a_refs.size(), 1);  // all references to "a" parameter
  for (const auto& a_ref : a_refs) {
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, &a_variable);  // pre-resolved
  }

  // Submodule "n"
  MUST_ASSIGN_LOOKUP_SYMBOL(module_n, module_m, "n");
  EXPECT_EQ(module_n_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_n_info.file_origin, &src);
  EXPECT_EQ(module_n_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(module_n_info.local_references_to_bind.size(), 1);
  const auto n_ref_map(module_n_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(n_a_refs, n_ref_map, "a");
  ASSERT_EQ(n_a_refs.size(), 1);  // references to "a" net in "n" module
  for (const auto& n_a_ref : n_a_refs) {
    const ReferenceComponent& n_a_ref_comp(n_a_ref->components->Value());
    EXPECT_EQ(n_a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(n_a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(n_a_ref_comp.identifier, "a");
    EXPECT_EQ(n_a_ref_comp.resolved_symbol,
              nullptr);  // resolving only in same scope
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    // Resolve mustn't break anything
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "a" resolved.
    for (const auto& a_ref : a_refs) {
      const ReferenceComponent& a_ref_comp(a_ref->components->Value());
      EXPECT_EQ(a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }

    for (const auto& n_a_ref : n_a_refs) {
      const ReferenceComponent& n_a_ref_comp(n_a_ref->components->Value());
      EXPECT_EQ(n_a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleExplicitDeclarationInSubScope) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;"
                            " assign a = 1'b0;"
                            " module n;"
                            "  wire a;"
                            "  assign a = 1'b1;"
                            " endmodule;"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(a_variable, module_m, "a");
  EXPECT_EQ(a_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* a_type_ref =
      a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(a_type_ref, nullptr);  // implicit type is primitive type
  EXPECT_TRUE(a_variable_info.declared_type.implicit);

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 1);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(a_refs, ref_map, "a");
  ASSERT_EQ(a_refs.size(), 1);  // all references to "a" parameter
  for (const auto& a_ref : a_refs) {
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, &a_variable);  // pre-resolved
  }

  // Submodule "n"
  MUST_ASSIGN_LOOKUP_SYMBOL(module_n, module_m, "n");
  EXPECT_EQ(module_n_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_n_info.file_origin, &src);
  EXPECT_EQ(module_n_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(n_a_variable, module_n, "a");
  EXPECT_EQ(n_a_variable_info.metatype,
            SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* n_a_type_ref =
      n_a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(n_a_type_ref, nullptr);
  EXPECT_FALSE(n_a_variable_info.declared_type.implicit);

  EXPECT_EQ(module_n_info.local_references_to_bind.size(), 1);
  const auto n_ref_map(module_n_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(n_a_refs, n_ref_map, "a");
  ASSERT_EQ(n_a_refs.size(), 1);  // references to "a" net in "n" module
  for (const auto& n_a_ref : n_a_refs) {
    const ReferenceComponent& n_a_ref_comp(n_a_ref->components->Value());
    EXPECT_EQ(n_a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(n_a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(n_a_ref_comp.identifier, "a");
    EXPECT_EQ(n_a_ref_comp.resolved_symbol,
              nullptr);  // resolving only in same scope
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    // Resolve mustn't break anything
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "a" resolved.
    for (const auto& a_ref : a_refs) {
      const ReferenceComponent& a_ref_comp(a_ref->components->Value());
      EXPECT_EQ(a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }

    for (const auto& n_a_ref : n_a_refs) {
      const ReferenceComponent& n_a_ref_comp(n_a_ref->components->Value());
      EXPECT_EQ(n_a_ref_comp.resolved_symbol,
                &n_a_variable);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleExplicitAndImplicitDeclarations) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;"
                            "wire b;"
                            "assign a = 1'b0;"
                            "assign b = 1'b1;"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_m, root_symbol, "m");
  EXPECT_EQ(module_m_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_m_info.file_origin, &src);
  EXPECT_EQ(module_m_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(a_variable, module_m, "a");
  EXPECT_EQ(a_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* a_type_ref =
      a_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(a_type_ref, nullptr);  // implicit type is primitive type
  EXPECT_TRUE(a_variable_info.declared_type.implicit);

  MUST_ASSIGN_LOOKUP_SYMBOL(b_variable, module_m, "b");
  EXPECT_EQ(b_variable_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* b_type_ref =
      b_variable_info.declared_type.user_defined_type;
  EXPECT_EQ(b_type_ref, nullptr);
  EXPECT_FALSE(b_variable_info.declared_type.implicit);

  EXPECT_EQ(module_m_info.local_references_to_bind.size(), 2);
  const auto ref_map(module_m_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(a_refs, ref_map, "a");
  ASSERT_EQ(a_refs.size(), 1);  // all references to "a" parameter
  for (const auto& a_ref : a_refs) {
    const ReferenceComponent& a_ref_comp(a_ref->components->Value());
    EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(a_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(a_ref_comp.identifier, "a");
    EXPECT_EQ(a_ref_comp.resolved_symbol, &a_variable);  // pre-resolved
  }

  ASSIGN_MUST_FIND(b_refs, ref_map, "b");
  ASSERT_EQ(b_refs.size(), 1);
  for (const auto& b_ref : b_refs) {
    const ReferenceComponent& b_ref_comp(b_ref->components->Value());
    EXPECT_EQ(b_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(b_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(b_ref_comp.identifier, "b");
    EXPECT_EQ(b_ref_comp.resolved_symbol, nullptr);
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    // Resolve mustn't break anything
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // All references to "a" resolved.
    for (const auto& a_ref : a_refs) {
      const ReferenceComponent& a_ref_comp(a_ref->components->Value());
      EXPECT_EQ(a_ref_comp.resolved_symbol,
                &a_variable);  // resolved successfully
    }

    // All references to "b" resolved.
    for (const auto& b_ref : b_refs) {
      const ReferenceComponent& b_ref_comp(b_ref->components->Value());
      EXPECT_EQ(b_ref_comp.resolved_symbol,
                &b_variable);  // resolved successfully
    }
  }
}

TEST(BuildSymbolTableTest, ModuleImplicitRedeclared) {
  TestVerilogSourceFile src("foo.sv",
                            "module m;\n"
                            "assign a = 1'b0;\n"
                            "wire a;\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EQ(build_diagnostics.size(), 1);
  EXPECT_FALSE(build_diagnostics.front().ok());
  EXPECT_EQ(build_diagnostics.front().message(),
            "foo.sv:3:6: Symbol \"a\" is already defined in the $root::m scope "
            "at 2:8:");
}

TEST(BuildSymbolTableTest, ClassDeclarationSingle) {
  TestVerilogSourceFile src("foobar.sv", "class ccc;\nendclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(ccc, root_symbol, "ccc");
  EXPECT_EQ(ccc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(ccc_info.file_origin, &src);
  EXPECT_EQ(ccc_info.declared_type.syntax_origin,
            nullptr);  // there is no module meta-type

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationNested) {
  TestVerilogSourceFile src("foobar.sv",
                            "package pp;\n"
                            "  class c_outer;\n"
                            "    class c_inner;\n"
                            "    endclass\n"
                            "  endclass\n"
                            "endpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");
  EXPECT_EQ(pp_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(pp_info.file_origin, &src);
  EXPECT_EQ(pp_info.declared_type.syntax_origin,
            nullptr);  // there is no package meta-type
  {
    MUST_ASSIGN_LOOKUP_SYMBOL(c_outer, pp, "c_outer");
    EXPECT_EQ(c_outer_info.metatype, SymbolMetaType::kClass);
    EXPECT_EQ(c_outer_info.file_origin, &src);
    EXPECT_EQ(c_outer_info.declared_type.syntax_origin,
              nullptr);  // there is no class meta-type
    {
      MUST_ASSIGN_LOOKUP_SYMBOL(c_inner, c_outer, "c_inner");
      EXPECT_EQ(c_inner_info.metatype, SymbolMetaType::kClass);
      EXPECT_EQ(c_inner_info.file_origin, &src);
      EXPECT_EQ(c_inner_info.declared_type.syntax_origin,
                nullptr);  // there is no class meta-type
    }
  }
  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);  // nothing to resolve
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationWithParameter) {
  TestVerilogSourceFile src("foobar.sv",
                            "class cc #(\n"
                            "  int N = 2\n"
                            ");\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_cc_info.file_origin, &src);
  EXPECT_EQ(class_cc_info.declared_type.syntax_origin,
            nullptr);  // there is no class meta-type

  MUST_ASSIGN_LOOKUP_SYMBOL(n_param, class_cc, "N");
  EXPECT_EQ(n_param_info.metatype, SymbolMetaType::kParameter);
  const ReferenceComponentNode* n_type_ref =
      n_param_info.declared_type.user_defined_type;
  EXPECT_EQ(n_type_ref, nullptr);  // int is primitive type

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationDataMember) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "class cc;\n"
                            "  int size;\n"
                            "  int count = 0;\n"  // with initializer
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_cc_info.file_origin, &src);
  EXPECT_EQ(class_cc_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(size_field, class_cc, "size");
  EXPECT_EQ(size_field_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* size_type_ref =
      size_field_info.declared_type.user_defined_type;
  EXPECT_EQ(size_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*size_field_info.declared_type.syntax_origin),
      "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(count_field, class_cc, "count");
  EXPECT_EQ(count_field_info.metatype,
            SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* count_type_ref =
      count_field_info.declared_type.user_defined_type;
  EXPECT_EQ(count_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *count_field_info.declared_type.syntax_origin),
            "int");

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());

  {  // No references.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationDataMemberMultiDeclaration) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "class cc;\n"
                            "  real height, width;\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_cc_info.file_origin, &src);
  EXPECT_EQ(class_cc_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(height_field, class_cc, "height");
  EXPECT_EQ(height_field_info.metatype,
            SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* height_type_ref =
      height_field_info.declared_type.user_defined_type;
  EXPECT_EQ(height_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *height_field_info.declared_type.syntax_origin),
            "real");

  MUST_ASSIGN_LOOKUP_SYMBOL(width_field, class_cc, "width");
  EXPECT_EQ(width_field_info.metatype,
            SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* width_type_ref =
      width_field_info.declared_type.user_defined_type;
  EXPECT_EQ(width_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *width_field_info.declared_type.syntax_origin),
            "real");

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());

  {  // No references.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationDataMemberAccessedFromMethod) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "class cc;\n"
                            "  int size;\n"
                            "  function int get_size();\n"
                            "    return size;\n"
                            "  endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_cc_info.file_origin, &src);
  EXPECT_EQ(class_cc_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(size_field, class_cc, "size");
  EXPECT_EQ(size_field_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* size_type_ref =
      size_field_info.declared_type.user_defined_type;
  EXPECT_EQ(size_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*size_field_info.declared_type.syntax_origin),
      "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(get_size, class_cc, "get_size");
  EXPECT_EQ(get_size_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(get_size_info.file_origin, &src);
  const auto ref_map(get_size_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(size_ref, ref_map, "size");
  const ReferenceComponent& size_ref_comp(size_ref->components->Value());
  EXPECT_EQ(size_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(size_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(size_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // "size" resolved to class data member
    EXPECT_EQ(size_ref_comp.resolved_symbol, &size_field);
  }
}

TEST(BuildSymbolTableTest, ClassDataMemberAccessedDirectly) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "class cc;\n"
                            "  int size;\n"
                            "endclass\n"
                            "function int get_size();\n"
                            "  cc cc_data;\n"
                            "  return cc_data.size;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_cc_info.file_origin, &src);
  EXPECT_EQ(class_cc_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(size_field, class_cc, "size");
  EXPECT_EQ(size_field_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  const ReferenceComponentNode* size_type_ref =
      size_field_info.declared_type.user_defined_type;
  EXPECT_EQ(size_type_ref, nullptr);  // int is primitive type
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*size_field_info.declared_type.syntax_origin),
      "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(get_size, root_symbol, "get_size");
  EXPECT_EQ(get_size_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(get_size_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_data, get_size, "cc_data");
  EXPECT_EQ(cc_data_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  const auto ref_map(get_size_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_data_ref, ref_map, "cc_data");
  const ReferenceComponent& cc_data_ref_comp(cc_data_ref->components->Value());
  EXPECT_EQ(cc_data_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_data_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_data_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(cc_data_ref->components->Children().size(), 1);
  const ReferenceComponentNode& size_ref(
      cc_data_ref->components->Children().front());
  const ReferenceComponent& size_ref_comp(size_ref.Value());
  EXPECT_EQ(size_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(size_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(size_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // "size" resolved to class data member
    EXPECT_EQ(size_ref_comp.resolved_symbol, &size_field);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationSingleInheritance) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "class base;\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  // "base" is referenced from the scope that contains "derived"
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(base_ref, ref_map, "base");
  const ReferenceComponent& base_ref_comp(base_ref->components->Value());
  EXPECT_EQ(base_ref_comp.identifier, "base");
  EXPECT_EQ(base_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(base_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" type reference to the "base" class.
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationSingleInheritanceAcrossPackage) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "package pp;\n"
                            "  class base;\n"
                            "  endclass\n"
                            "endpackage\n"
                            "class derived extends pp::base;\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  EXPECT_EQ(package_pp_info.metatype, SymbolMetaType::kPackage);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, package_pp, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  // "pp::base" is referenced from the scope that contains "derived"
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_ref, ref_map, "pp");
  const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
  EXPECT_EQ(pp_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(pp_ref->components->Children().size(), 1);
  const ReferenceComponentNode& base_ref(
      pp_ref->components->Children().front());
  const ReferenceComponent& base_ref_comp(base_ref.Value());
  EXPECT_EQ(base_ref_comp.identifier, "base");
  EXPECT_EQ(base_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(base_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_ref_comp.resolved_symbol, nullptr);

  // Make sure the "pp::base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "pp::base" type reference to the "pp::base" class.
    EXPECT_EQ(pp_ref_comp.resolved_symbol, &package_pp);
    EXPECT_EQ(base_ref_comp.resolved_symbol, &base_class);
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationSingleInheritancePackageToPackage) {
  TestVerilogSourceFile src("member_accessor.sv",
                            "package pp;\n"
                            "  class base;\n"
                            "  endclass\n"
                            "endpackage\n"
                            "package qq;\n"
                            "  class derived extends pp::base;\n"
                            "  endclass\n"
                            "endpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  EXPECT_EQ(package_pp_info.metatype, SymbolMetaType::kPackage);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, package_pp, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(package_qq, root_symbol, "qq");
  EXPECT_EQ(package_qq_info.metatype, SymbolMetaType::kPackage);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, package_qq, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  // "pp::base" is referenced from the scope that contains "derived",
  // which is package "qq".
  EXPECT_EQ(package_qq_info.local_references_to_bind.size(), 1);
  const auto ref_map(package_qq_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_ref, ref_map, "pp");
  const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
  EXPECT_EQ(pp_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(pp_ref->components->Children().size(), 1);
  const ReferenceComponentNode& base_ref(
      pp_ref->components->Children().front());
  const ReferenceComponent& base_ref_comp(base_ref.Value());
  EXPECT_EQ(base_ref_comp.identifier, "base");
  EXPECT_EQ(base_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(base_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_ref_comp.resolved_symbol, nullptr);

  // Make sure the "pp::base" reference is linked from the "qq::derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      package_qq_info.local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "pp::base" type reference to the "pp::base" class.
    EXPECT_EQ(pp_ref_comp.resolved_symbol, &package_pp);
    EXPECT_EQ(base_ref_comp.resolved_symbol, &base_class);
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationInheritanceFromNestedClass) {
  TestVerilogSourceFile src("classilicious.sv",
                            "class pp;\n"
                            "  class base;\n"
                            "  endclass\n"
                            "endclass\n"
                            "class qq;\n"
                            "  class derived extends pp::base;\n"
                            "  endclass\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_pp, root_symbol, "pp");
  EXPECT_EQ(class_pp_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, class_pp, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(class_qq, root_symbol, "qq");
  EXPECT_EQ(class_qq_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, class_qq, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  // "pp::base" is referenced from the scope that contains "derived",
  // which is package "qq".
  EXPECT_EQ(class_qq_info.local_references_to_bind.size(), 1);
  const auto ref_map(class_qq_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_ref, ref_map, "pp");
  const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
  EXPECT_EQ(pp_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(pp_ref->components->Children().size(), 1);
  const ReferenceComponentNode& base_ref(
      pp_ref->components->Children().front());
  const ReferenceComponent& base_ref_comp(base_ref.Value());
  EXPECT_EQ(base_ref_comp.identifier, "base");
  EXPECT_EQ(base_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(base_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_ref_comp.resolved_symbol, nullptr);

  // Make sure the "pp::base" reference is linked from the "qq::derived" class.
  ASSERT_EQ(derived_class_info.parent_type.user_defined_type,
            class_qq_info.local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "pp::base" type reference to the "pp::base" class.
    EXPECT_EQ(pp_ref_comp.resolved_symbol, &class_pp);
    EXPECT_EQ(base_ref_comp.resolved_symbol, &base_class);
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationInLineConstructorDefinition) {
  TestVerilogSourceFile src("ctor.sv",
                            "class C;\n"
                            "  function new();\n"
                            "  endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_c, root_symbol, "C");
  EXPECT_EQ(class_c_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_c_info.file_origin, &src);
  EXPECT_EQ(class_c_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(ctor, class_c, "new");
  EXPECT_EQ(ctor_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(ctor_info.file_origin, &src);
  EXPECT_NE(ctor_info.syntax_origin, nullptr);
  EXPECT_NE(ctor_info.declared_type.syntax_origin, nullptr);  // points to "new"
  // constructor is already known to "return" its class type
  EXPECT_EQ(ctor_info.declared_type.user_defined_type->Value().resolved_symbol,
            &class_c);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationOutOfLineConstructorDefinition) {
  TestVerilogSourceFile src("ctor.sv",
                            "class C;\n"
                            "  extern function new;\n"
                            "endclass\n"
                            "function C::new ();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_c, root_symbol, "C");
  EXPECT_EQ(class_c_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(class_c_info.file_origin, &src);
  EXPECT_EQ(class_c_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(ctor, class_c, "new");
  EXPECT_EQ(ctor_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(ctor_info.file_origin, &src);
  EXPECT_NE(ctor_info.syntax_origin, nullptr);
  EXPECT_NE(ctor_info.declared_type.syntax_origin, nullptr);  // points to "new"
  // constructor is already known to "return" its class type
  EXPECT_EQ(ctor_info.declared_type.user_defined_type->Value().resolved_symbol,
            &class_c);

  // Expect a "C::new" reference from the out-of-line definition.
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(class_c_ref, ref_map, "C");
  const ReferenceComponent& c_ref_comp(class_c_ref->components->Value());
  EXPECT_EQ(c_ref_comp.identifier, "C");
  EXPECT_EQ(c_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(c_ref_comp.required_metatype, SymbolMetaType::kClass);
  // out-of-line class and method reference must be resolved at build-time
  EXPECT_NE(c_ref_comp.resolved_symbol, nullptr);
  const ReferenceComponent& ctor_ref_comp(class_c_ref->LastLeaf()->Value());
  EXPECT_EQ(ctor_ref_comp.identifier, "new");
  EXPECT_EQ(ctor_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(ctor_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_NE(ctor_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(c_ref_comp.resolved_symbol, &class_c);  // class C
    EXPECT_EQ(ctor_ref_comp.resolved_symbol, &ctor);  // function C::new
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationReferenceInheritedMemberFromMethod) {
  TestVerilogSourceFile src("member_from_parent.sv",
                            "class base;\n"
                            "  int count;\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "  function int get_count();\n"
                            "    return count;\n"
                            "  endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, base_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_count_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, derived_class, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  ASSERT_EQ(get_count_info.local_references_to_bind.size(), 1);

  // "base::count" is referenced from the "derived::get_count" method
  EXPECT_EQ(get_count_info.local_references_to_bind.size(), 1);
  const auto ref_map(get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(count_ref, ref_map, "count");
  const ReferenceComponent& count_ref_comp(count_ref->components->Value());
  EXPECT_EQ(count_ref_comp.identifier, "count");
  EXPECT_EQ(count_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(count_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" type reference to the "base" class.
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
    // "count" in "get_count" resolved to "base::count"
    EXPECT_EQ(count_ref_comp.resolved_symbol, &int_count);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationReferenceGrandparentMember) {
  TestVerilogSourceFile src("member_from_parent.sv",
                            "class base;\n"
                            "  int count;\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "endclass\n"
                            "class more_derived extends derived;\n"
                            "  function int get_count();\n"
                            "    return count;\n"
                            "  endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, base_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_count_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(more_derived_class, root_symbol, "more_derived");
  EXPECT_EQ(more_derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(more_derived_class_info.file_origin, &src);
  EXPECT_EQ(more_derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(more_derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, more_derived_class, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  ASSERT_EQ(get_count_info.local_references_to_bind.size(), 1);

  // "base::count" is referenced from the "more_derived::get_count" method
  EXPECT_EQ(get_count_info.local_references_to_bind.size(), 1);
  const auto ref_map(get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(count_ref, ref_map, "count");
  const ReferenceComponent& count_ref_comp(count_ref->components->Value());
  EXPECT_EQ(count_ref_comp.identifier, "count");
  EXPECT_EQ(count_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(count_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  // Make sure the "derived" reference is linked from the "more_derived" class.
  const auto root_refs = root_symbol.Value().LocalReferencesMapViewForTesting();
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(base_ref, root_refs, "base");
  const ReferenceComponent& base_ref_comp(base_ref->components->Value());
  EXPECT_EQ(base_ref_comp.identifier, "base");
  EXPECT_EQ(base_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(base_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(derived_ref, root_refs, "derived");
  const ReferenceComponent& derived_ref_comp(derived_ref->components->Value());
  EXPECT_EQ(derived_ref_comp.identifier, "derived");
  EXPECT_EQ(derived_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(derived_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(derived_class_info.parent_type.user_defined_type,
            base_ref->LastTypeComponent());
  EXPECT_EQ(more_derived_class_info.parent_type.user_defined_type,
            derived_ref->LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" and "derived" type references
    EXPECT_EQ(base_ref_comp.resolved_symbol, &base_class);
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
    EXPECT_EQ(derived_ref_comp.resolved_symbol, &derived_class);
    EXPECT_EQ(more_derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &derived_class);
    // "count" in "more_derived::get_count" resolved to "base::count"
    EXPECT_EQ(count_ref_comp.resolved_symbol, &int_count);
  }
}

TEST(BuildSymbolTableTest,
     ClassDeclarationReferenceInheritedMemberDirectAccess) {
  TestVerilogSourceFile src("member_from_parent.sv",
                            "class base;\n"
                            "  int count;\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "endclass\n"
                            "function int get_count(derived dd);\n"
                            "  return dd.count;\n"  // direct member access
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, base_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_count_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, root_symbol, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  // references "derived" as a type and "dd" as an argument
  ASSERT_EQ(get_count_info.local_references_to_bind.size(), 2);

  MUST_ASSIGN_LOOKUP_SYMBOL(dd_arg, get_count, "dd");
  EXPECT_EQ(dd_arg_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(dd_arg_info.declared_type.user_defined_type, nullptr);
  EXPECT_EQ(dd_arg_info.declared_type.user_defined_type->Value().identifier,
            "derived");
  EXPECT_EQ(
      dd_arg_info.declared_type.user_defined_type->Value().resolved_symbol,
      nullptr);

  // "base::count" is referenced from the "dd.count"
  const auto ref_map(get_count_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(derived_type_ref, ref_map, "derived");
  const ReferenceComponent& derived_type_ref_comp(
      derived_type_ref->components->Value());
  EXPECT_EQ(derived_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(derived_type_ref_comp.required_metatype,
            SymbolMetaType::kUnspecified);
  EXPECT_EQ(derived_type_ref_comp.identifier, "derived");
  EXPECT_EQ(derived_type_ref_comp.resolved_symbol, nullptr);
  // Make sure "derived dd"'s type uses this type reference.
  EXPECT_EQ(dd_arg_info.declared_type.user_defined_type,
            derived_type_ref->components.get());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_ref, ref_map, "dd");
  const ReferenceComponent& dd_ref_comp(dd_ref->components->Value());
  EXPECT_EQ(dd_ref_comp.identifier, "dd");
  EXPECT_EQ(dd_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(dd_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(dd_ref->components->Children().size(), 1);
  const ReferenceComponentNode& dd_count_ref(
      dd_ref->components->Children().front());
  const ReferenceComponent& dd_count_ref_comp(dd_count_ref.Value());
  EXPECT_EQ(dd_count_ref_comp.identifier, "count");
  EXPECT_EQ(dd_count_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_count_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" type reference to the "base" class.
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
    // "dd"'s type resolved to "derived"
    EXPECT_EQ(
        dd_arg_info.declared_type.user_defined_type->Value().resolved_symbol,
        &derived_class);
    // "dd" references function parameter
    EXPECT_EQ(dd_ref_comp.resolved_symbol, &dd_arg);
    // "count" in "dd.count" resolved to "base::count"
    EXPECT_EQ(dd_count_ref_comp.resolved_symbol, &int_count);
  }
}

TEST(BuildSymbolTableTest, ClassDeclarationReferenceInheritedBaseClassMethod) {
  TestVerilogSourceFile src("member_from_parent.sv",
                            "class base;\n"
                            "  function int count();\n"
                            "  endfunction\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "  function int get_count();\n"
                            "    return count();\n"
                            "  endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, base_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(int_count_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, derived_class, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  ASSERT_EQ(get_count_info.local_references_to_bind.size(), 1);

  // "base::count" is referenced from the "derived::get_count" method
  EXPECT_EQ(get_count_info.local_references_to_bind.size(), 1);
  const auto ref_map(get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(count_ref, ref_map, "count");
  const ReferenceComponent& count_ref_comp(count_ref->components->Value());
  EXPECT_EQ(count_ref_comp.identifier, "count");
  EXPECT_EQ(count_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(count_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(count_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" type reference to the "base" class.
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
    // "count" in "get_count" resolved to "base::count"
    EXPECT_EQ(count_ref_comp.resolved_symbol, &int_count);
  }
}

TEST(BuildSymbolTableTest,
     ClassDeclarationReferenceInheritedBaseMethodFromObject) {
  TestVerilogSourceFile src("member_from_parent.sv",
                            "class base;\n"
                            "  function int count();\n"
                            "  endfunction\n"
                            "endclass\n"
                            "class derived extends base;\n"
                            "endclass\n"
                            "function int get_count(derived dd);\n"
                            "  return dd.count();\n"  // method call
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);
  EXPECT_EQ(base_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(base_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, base_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(int_count_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);
  EXPECT_EQ(derived_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(derived_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, root_symbol, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  // references "derived" as a type and "dd" as an argument
  ASSERT_EQ(get_count_info.local_references_to_bind.size(), 2);

  MUST_ASSIGN_LOOKUP_SYMBOL(dd_arg, get_count, "dd");
  EXPECT_EQ(dd_arg_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(dd_arg_info.declared_type.user_defined_type, nullptr);
  EXPECT_EQ(dd_arg_info.declared_type.user_defined_type->Value().identifier,
            "derived");
  EXPECT_EQ(
      dd_arg_info.declared_type.user_defined_type->Value().resolved_symbol,
      nullptr);

  // "base::count" is referenced from the "dd.count"
  const auto ref_map(get_count_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(derived_type_ref, ref_map, "derived");
  const ReferenceComponent& derived_type_ref_comp(
      derived_type_ref->components->Value());
  EXPECT_EQ(derived_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(derived_type_ref_comp.required_metatype,
            SymbolMetaType::kUnspecified);
  EXPECT_EQ(derived_type_ref_comp.identifier, "derived");
  EXPECT_EQ(derived_type_ref_comp.resolved_symbol, nullptr);
  // Make sure "derived dd"'s type uses this type reference.
  EXPECT_EQ(dd_arg_info.declared_type.user_defined_type,
            derived_type_ref->components.get());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_ref, ref_map, "dd");
  const ReferenceComponent& dd_ref_comp(dd_ref->components->Value());
  EXPECT_EQ(dd_ref_comp.identifier, "dd");
  EXPECT_EQ(dd_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(dd_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_ref_comp.resolved_symbol, nullptr);

  ASSERT_EQ(dd_ref->components->Children().size(), 1);
  const ReferenceComponentNode& dd_count_ref(
      dd_ref->components->Children().front());
  const ReferenceComponent& dd_count_ref_comp(dd_count_ref.Value());
  EXPECT_EQ(dd_count_ref_comp.identifier, "count");
  EXPECT_EQ(dd_count_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_count_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(dd_count_ref_comp.resolved_symbol, nullptr);

  // Make sure the "base" reference is linked from the "derived" class.
  ASSERT_EQ(
      derived_class_info.parent_type.user_defined_type,
      root_symbol.Value().local_references_to_bind.front().LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve the "base" type reference to the "base" class.
    EXPECT_EQ(derived_class_info.parent_type.user_defined_type->Value()
                  .resolved_symbol,
              &base_class);
    // "dd"'s type resolved to "derived"
    EXPECT_EQ(
        dd_arg_info.declared_type.user_defined_type->Value().resolved_symbol,
        &derived_class);
    // "dd" references function parameter
    EXPECT_EQ(dd_ref_comp.resolved_symbol, &dd_arg);
    // "count()" in "dd.count()" resolved to "base::count()"
    EXPECT_EQ(dd_count_ref_comp.resolved_symbol, &int_count);
  }
}

TEST(BuildSymbolTableTest, TypeParameterizedModuleDeclaration) {
  TestVerilogSourceFile src("camelot_param_alot.sv",
                            "module mm #(parameter type T = bit);\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(mm_module, root_symbol, "mm");
  EXPECT_EQ(mm_module_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(mm_module_info.file_origin, &src);
  EXPECT_EQ(mm_module_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(mm_module_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, mm_module, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());

  {  // No references.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TypeParameterizedClassDataDeclarations) {
  TestVerilogSourceFile src("i_push_the_param_alot.sv",
                            "class cc #(parameter type T = bit);\n"
                            "endclass\n"
                            "cc#(cc#(int)) data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, root_symbol, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);
  EXPECT_EQ(cc_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(cc_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 2);

  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(cc_refs, ref_map, "cc");
  EXPECT_EQ(cc_refs.size(), 2);

  for (const auto& cc_ref : cc_refs) {
    const ReferenceComponent& cc_ref_comp(cc_ref->components->Value());
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);
  }

  // Of the two "cc" type refs, the outer one is the first one, by ordering of
  // textual position among references that start with the same identifier.
  const DependentReferences& data_cc_type(**cc_refs.begin());
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            data_cc_type.LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    for (const auto& cc_ref : cc_refs) {
      const ReferenceComponent& cc_ref_comp(cc_ref->components->Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);
    }
    // type of "data" is resolved
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &cc_class);
  }
}

TEST(BuildSymbolTableTest,
     TypeParameterizedClassDataDeclarationsPackageQualifiedTwoParams) {
  TestVerilogSourceFile src(
      "i_eat_ham_and_jam_and_spam_alot.sv",
      "package pp;\n"
      "  class cc #(\n"
      "    parameter type T1 = bit,\n"
      "    parameter type T2 = bit\n"
      "  );\n"
      "  endclass\n"
      "endpackage\n"
      "pp::cc#(pp::cc#(int, bit), pp::cc#(bit, int)) data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp_package, root_symbol, "pp");
  EXPECT_EQ(pp_package_info.metatype, SymbolMetaType::kPackage);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, pp_package, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);
  EXPECT_EQ(cc_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(cc_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(t1_type_param, cc_class, "T1");
  EXPECT_EQ(t1_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t1_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(t2_type_param, cc_class, "T2");
  EXPECT_EQ(t2_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t2_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 3);

  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(pp_refs, ref_map, "pp");
  EXPECT_EQ(pp_refs.size(), 3);

  // all "pp::cc" references have the same structure
  for (const auto& pp_ref : pp_refs) {
    const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
    EXPECT_EQ(pp_ref_comp.identifier, "pp");
    EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

    ASSERT_EQ(pp_ref->components->Children().size(), 1);
    const ReferenceComponentNode& cc_ref(
        pp_ref->components->Children().front());
    const ReferenceComponent& cc_ref_comp(cc_ref.Value());
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);
  }

  // Of all the "pp::cc" type refs, the outer one is the first one, by ordering
  // of textual position among references that start with the same identifier.
  const DependentReferences& data_cc_type(**pp_refs.begin());
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            data_cc_type.LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    for (const auto& pp_ref : pp_refs) {
      const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
      EXPECT_EQ(pp_ref_comp.resolved_symbol, &pp_package);

      const ReferenceComponentNode& cc_ref(
          pp_ref->components->Children().front());
      const ReferenceComponent& cc_ref_comp(cc_ref.Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);
    }
    // type of "data" is resolved
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &cc_class);
  }
}

TEST(BuildSymbolTableTest, NestedTypeParameterizedClassDataDeclaration) {
  TestVerilogSourceFile src(
      "its_fun_down_here_in_Camelot.sv",
      "class outer #(parameter type S = int);\n"
      "  class cc #(parameter type T = bit);\n"
      "  endclass\n"
      "endclass\n"
      "outer#(outer#(int)::cc#(int))::cc#(outer#(bit)::cc#(bit)) data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(outer_class, root_symbol, "outer");
  EXPECT_EQ(outer_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(outer_class_info.file_origin, &src);
  EXPECT_EQ(outer_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(outer_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(s_type_param, outer_class, "S");
  EXPECT_EQ(s_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(s_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, outer_class, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);
  EXPECT_EQ(cc_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(cc_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 3);

  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(outer_refs, ref_map, "outer");
  EXPECT_EQ(outer_refs.size(), 3);

  // all "pp::cc" references have the same structure
  for (const auto& outer_ref : outer_refs) {
    const ReferenceComponent& outer_ref_comp(outer_ref->components->Value());
    EXPECT_EQ(outer_ref_comp.identifier, "outer");
    EXPECT_EQ(outer_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(outer_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(outer_ref_comp.resolved_symbol, nullptr);

    ASSERT_EQ(outer_ref->components->Children().size(), 1);
    const ReferenceComponentNode& cc_ref(
        outer_ref->components->Children().front());
    const ReferenceComponent& cc_ref_comp(cc_ref.Value());
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);
  }

  // Of all the "outer::cc" type refs, the outer one is the first one, by
  // ordering of textual position among references that start with the same
  // identifier.
  const DependentReferences& data_cc_type(**outer_refs.begin());
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            data_cc_type.LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    for (const auto& outer_ref : outer_refs) {
      const ReferenceComponent& outer_ref_comp(outer_ref->components->Value());
      EXPECT_EQ(outer_ref_comp.resolved_symbol, &outer_class);

      const ReferenceComponentNode& cc_ref(
          outer_ref->components->Children().front());
      const ReferenceComponent& cc_ref_comp(cc_ref.Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);
    }
    // type of "data" is resolved
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &cc_class);
  }
}

TEST(BuildSymbolTableTest,
     TypeParameterizedClassDataDeclarationNamedParameters) {
  TestVerilogSourceFile src("its_fun_down_here_in_Camelot.sv",
                            "class cc #(\n"
                            "  parameter type S = int,\n"
                            "  parameter type T = bit\n"
                            ");\n"
                            "endclass\n"
                            "cc#(.S(int), .T(int)) data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, root_symbol, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);
  EXPECT_EQ(cc_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(cc_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(s_type_param, cc_class, "S");
  EXPECT_EQ(s_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(s_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(cc_refs, ref_map, "cc");
  ASSIGN_MUST_HAVE_UNIQUE(cc_ref, cc_refs);
  const ReferenceComponent& cc_ref_comp(cc_ref->components->Value());
  EXPECT_EQ(cc_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentMap param_ref_map(
      ReferenceComponentNodeMapView(*cc_ref->components));
  ASSIGN_MUST_FIND(s_ref, param_ref_map, "S");
  const ReferenceComponent& s_ref_comp(s_ref->Value());
  EXPECT_EQ(s_ref_comp.identifier, "S");
  EXPECT_EQ(s_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(s_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(s_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(t_ref, param_ref_map, "T");
  const ReferenceComponent& t_ref_comp(t_ref->Value());
  EXPECT_EQ(t_ref_comp.identifier, "T");
  EXPECT_EQ(t_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(t_ref_comp.required_metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_ref_comp.resolved_symbol, nullptr);

  const DependentReferences& data_cc_type(*cc_ref);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            data_cc_type.components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);
    EXPECT_EQ(s_ref_comp.resolved_symbol, &s_type_param);
    EXPECT_EQ(t_ref_comp.resolved_symbol, &t_type_param);
    // type of "data" is resolved
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &cc_class);
  }
}

TEST(BuildSymbolTableTest,
     NestedTypeParameterizedClassDataDeclarationNamedParameters) {
  TestVerilogSourceFile src(
      "i_need_to_upgrade_my_RAM_alot.sv",
      "class outer #(parameter type S = int);\n"
      "  class cc #(parameter type T = bit);\n"
      "  endclass\n"
      "endclass\n"
      "outer#(.S(outer#(.S(int))::cc#(.T(int))))\n"
      "    ::cc#(.T(outer#(.S(bit))::cc#(.T(bit)))) data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(outer_class, root_symbol, "outer");
  EXPECT_EQ(outer_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(outer_class_info.file_origin, &src);
  EXPECT_EQ(outer_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(outer_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(s_type_param, outer_class, "S");
  EXPECT_EQ(s_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(s_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, outer_class, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);
  EXPECT_EQ(cc_class_info.declared_type.syntax_origin, nullptr);
  EXPECT_TRUE(cc_class_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 3);

  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(outer_refs, ref_map, "outer");
  EXPECT_EQ(outer_refs.size(), 3);

  // all "outer::cc" references have the same structure
  for (const auto& outer_ref : outer_refs) {
    const ReferenceComponent& outer_ref_comp(outer_ref->components->Value());
    EXPECT_EQ(outer_ref_comp.identifier, "outer");
    EXPECT_EQ(outer_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(outer_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(outer_ref_comp.resolved_symbol, nullptr);

    ASSERT_EQ(outer_ref->components->Children().size(), 2);

    const ReferenceComponentNode& s_param_ref(
        outer_ref->components->Children().front());
    const ReferenceComponent& s_param_ref_comp(s_param_ref.Value());
    EXPECT_EQ(s_param_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(s_param_ref_comp.required_metatype, SymbolMetaType::kParameter);
    EXPECT_EQ(s_param_ref_comp.identifier, "S");
    EXPECT_EQ(s_param_ref_comp.resolved_symbol, nullptr);

    const ReferenceComponentNode& cc_ref(
        outer_ref->components->Children().back());
    const ReferenceComponent& cc_ref_comp(cc_ref.Value());
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

    ASSERT_EQ(cc_ref.Children().size(), 1);
    const ReferenceComponentNode& t_param_ref(cc_ref.Children().front());
    const ReferenceComponent& t_param_ref_comp(t_param_ref.Value());
    EXPECT_EQ(t_param_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(t_param_ref_comp.required_metatype, SymbolMetaType::kParameter);
    EXPECT_EQ(t_param_ref_comp.identifier, "T");
    EXPECT_EQ(t_param_ref_comp.resolved_symbol, nullptr);
  }

  // Of all the "outer::cc" type refs, the outer one is the first one, by
  // ordering of textual position among references that start with the same
  // identifier.
  const DependentReferences& data_cc_type(**outer_refs.begin());
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            data_cc_type.LastTypeComponent());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    for (const auto& outer_ref : outer_refs) {
      const ReferenceComponent& outer_ref_comp(outer_ref->components->Value());
      EXPECT_EQ(outer_ref_comp.resolved_symbol, &outer_class);

      const ReferenceComponentNode& s_param_ref(
          outer_ref->components->Children().front());
      const ReferenceComponent& s_param_ref_comp(s_param_ref.Value());
      EXPECT_EQ(s_param_ref_comp.resolved_symbol, &s_type_param);

      const ReferenceComponentNode& cc_ref(
          outer_ref->components->Children().back());
      const ReferenceComponent& cc_ref_comp(cc_ref.Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);

      const ReferenceComponentNode& t_param_ref(cc_ref.Children().front());
      const ReferenceComponent& t_param_ref_comp(t_param_ref.Value());
      EXPECT_EQ(t_param_ref_comp.resolved_symbol, &t_type_param);
    }
    // type of "data" is resolved
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &cc_class);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationNoReturnType) {
  TestVerilogSourceFile src("funkytown.sv",
                            "function ff;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  // no return type
  EXPECT_EQ(function_ff_info.declared_type.syntax_origin, nullptr);

  EXPECT_TRUE(function_ff_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationWithPort) {
  TestVerilogSourceFile src("funkytown.sv",
                            "function ff(int g);\n"
                            "endfunction\n");
  // TODO: propagate type for ports like "int g, h"
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  EXPECT_EQ(function_ff_info.declared_type.syntax_origin,
            nullptr);  // there is no function return type

  MUST_ASSIGN_LOOKUP_SYMBOL(param_g, function_ff, "g");
  EXPECT_EQ(param_g_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(param_g_info.file_origin, &src);
  ASSERT_NE(param_g_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*param_g_info.declared_type.syntax_origin),
      "int");

  EXPECT_TRUE(function_ff_info.local_references_to_bind.empty());
  EXPECT_TRUE(param_g_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationWithLocalVariable) {
  TestVerilogSourceFile src("funkytown.sv",
                            "function ff();\n"
                            "  logic g;\n"
                            "endfunction\n");
  // TODO: propagate type for ports like "int g, h"
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  EXPECT_EQ(function_ff_info.declared_type.syntax_origin,
            nullptr);  // there is no function return type

  MUST_ASSIGN_LOOKUP_SYMBOL(local_g, function_ff, "g");
  EXPECT_EQ(local_g_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(local_g_info.file_origin, &src);
  ASSERT_NE(local_g_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*local_g_info.declared_type.syntax_origin),
      "logic");

  EXPECT_TRUE(function_ff_info.local_references_to_bind.empty());
  EXPECT_TRUE(local_g_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationVoidReturnType) {
  TestVerilogSourceFile src("funkytown.sv",
                            "function void ff;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  ASSERT_NE(function_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *function_ff_info.declared_type.syntax_origin),
            "void");

  EXPECT_TRUE(function_ff_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationClassReturnType) {
  TestVerilogSourceFile src("funkytown.sv",
                            "class cc;\n"
                            "endclass\n"
                            "function cc ff;\n"  // user-defined return type
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  ASSERT_NE(function_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *function_ff_info.declared_type.syntax_origin),
            "cc");
  const ReferenceComponentNode* cc_ref =
      function_ff_info.declared_type.user_defined_type;
  ASSERT_NE(cc_ref, nullptr);
  const ReferenceComponent& cc_ref_comp(cc_ref->Value());
  EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

  // There should be one reference to return type "cc" of function "ff".
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect "cc" return type to resolve to class declaration.
    EXPECT_EQ(cc_ref_comp.resolved_symbol, &class_cc);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationInModule) {
  TestVerilogSourceFile src("funkytown.sv",
                            "module mm;\n"
                            "function void ff();\n"
                            "endfunction\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_mm, root_symbol, "mm");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, module_mm, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  ASSERT_NE(function_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *function_ff_info.declared_type.syntax_origin),
            "void");
  const ReferenceComponentNode* ff_type =
      function_ff_info.declared_type.user_defined_type;
  EXPECT_EQ(ff_type, nullptr);

  // There are no references to resolve.
  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());
  EXPECT_TRUE(module_mm.Value().local_references_to_bind.empty());
  EXPECT_TRUE(function_ff.Value().local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, ClassMethodFunctionDeclaration) {
  TestVerilogSourceFile src("funkytown.sv",
                            "class cc;\n"
                            "function int ff;\n"
                            "endfunction\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, class_cc, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  ASSERT_NE(function_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *function_ff_info.declared_type.syntax_origin),
            "int");
  const ReferenceComponentNode* ff_type =
      function_ff_info.declared_type.user_defined_type;
  EXPECT_EQ(ff_type, nullptr);

  // There are no references to resolve.
  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());
  EXPECT_TRUE(class_cc.Value().local_references_to_bind.empty());
  EXPECT_TRUE(function_ff.Value().local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest,
     ClassMethodFunctionDeclarationPackageTypeReturnType) {
  TestVerilogSourceFile src("funkytown.sv",
                            "package aa;\n"
                            "class vv;\n"
                            "endclass\n"
                            "endpackage\n"
                            "package bb;\n"
                            "class cc;\n"
                            "function aa::vv ff();\n"
                            "endfunction\n"
                            "endclass\n"
                            "endpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_aa, root_symbol, "aa");
  MUST_ASSIGN_LOOKUP_SYMBOL(package_bb, root_symbol, "bb");
  MUST_ASSIGN_LOOKUP_SYMBOL(class_vv, package_aa, "vv");
  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, package_bb, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, class_cc, "ff");

  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);
  ASSERT_NE(function_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *function_ff_info.declared_type.syntax_origin),
            "aa::vv");

  // return type points to the last component of the chain, "vv"
  const ReferenceComponentNode* vv_ref =
      function_ff_info.declared_type.user_defined_type;
  ASSERT_NE(vv_ref, nullptr);
  const ReferenceComponent& vv_ref_comp(vv_ref->Value());
  EXPECT_EQ(vv_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(vv_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(vv_ref_comp.identifier, "vv");
  EXPECT_EQ(vv_ref_comp.resolved_symbol, nullptr);

  // dependent reference parent is "aa" in "aa::vv"
  const ReferenceComponentNode* aa_ref = vv_ref->Parent();
  ASSERT_NE(aa_ref, nullptr);
  const ReferenceComponent& aa_ref_comp(aa_ref->Value());
  EXPECT_EQ(aa_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(aa_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(aa_ref_comp.identifier, "aa");
  EXPECT_EQ(aa_ref_comp.resolved_symbol, nullptr);

  // There is only one (type) reference chain to resolve: "aa::vv".
  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());
  EXPECT_TRUE(package_aa.Value().local_references_to_bind.empty());
  EXPECT_TRUE(package_bb.Value().local_references_to_bind.empty());
  EXPECT_EQ(class_cc.Value().local_references_to_bind.size(), 1);
  EXPECT_TRUE(function_ff.Value().local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Expect to resolve type reference chain "aa:vv"
    EXPECT_EQ(aa_ref_comp.resolved_symbol, &package_aa);
    EXPECT_EQ(vv_ref_comp.resolved_symbol, &class_vv);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationOutOfLineMissingOuterClass) {
  TestVerilogSourceFile src("outofline_func.sv",
                            "function cc::ff;\n"  // "cc" undeclared
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"cc\" in parent scope (<root>) $root"));
  }

  // out-of-line declaration creates a self-reference.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    // Same diagnostic as before.
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"cc\" in parent scope (<root>) $root"));
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationOutOfLineInvalidModuleInjection) {
  TestVerilogSourceFile src("outofline_func.sv",
                            "module mm;\n"
                            "endmodule\n"
                            "function mm::ff;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    // Expect that "tt" will not injected into "mm" because it is a module,
    // not a class.
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"mm\" to resolve to a class, "
                          "but found a module"));
  }
  MUST_ASSIGN_LOOKUP_SYMBOL(module_mm, root_symbol, "mm");
  EXPECT_EQ(module_mm_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_mm.Find("ff"), module_mm.end());

  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(mm_ref, ref_map, "mm");
  EXPECT_EQ(mm_ref->components->Value().resolved_symbol, nullptr);

  // Method injection will not happen for modules.
  const ReferenceComponentNode* ff_ref = mm_ref->LastLeaf();
  const ReferenceComponent& ref(ff_ref->Value());
  EXPECT_EQ(ref.identifier, "ff");
  EXPECT_EQ(ref.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSERT_EQ(resolve_diagnostics.size(), 1);

    // Still remain unresolved.
    EXPECT_EQ(mm_ref->components->Value().resolved_symbol, nullptr);
    EXPECT_EQ(ref.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationOutOfLineMissingPrototype) {
  TestVerilogSourceFile src("outofline_func.sv",
                            "class cc;\n"
                            // no "ff" prototype
                            "endclass\n"
                            "function cc::ff;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    // This diagnostic is non-fatal.
    // Expect that "ff" will be injected into "cc" when its method prototype is
    // missing.
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"ff\" in parent scope (class) cc"));
  }
  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_ff, class_cc, "ff");
  EXPECT_EQ(method_ff_info.metatype, SymbolMetaType::kFunction);

  // out-of-line declaration creates a self-reference.
  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);

  // Method reference is resolved to the injected symbol.
  const ReferenceComponentNode* ff_ref = cc_ref->LastLeaf();
  const ReferenceComponent& ref(ff_ref->Value());
  EXPECT_EQ(ref.identifier, "ff");
  EXPECT_EQ(ref.resolved_symbol, &method_ff);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Already resolved before, still remains resolved.
    EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);
    EXPECT_EQ(ref.resolved_symbol, &method_ff);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationMethodPrototypeOnly) {
  TestVerilogSourceFile src("outofline_func.sv",
                            "class cc;\n"
                            "  extern function int ff(logic ll);\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_ff, class_cc, "ff");
  EXPECT_EQ(method_ff_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(method_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*method_ff_info.declared_type.syntax_origin),
      "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(port_ll, method_ff, "ll");
  EXPECT_EQ(port_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(port_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*port_ll_info.declared_type.syntax_origin),
      "logic");

  // No references to resolve.
  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());
  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());
  EXPECT_TRUE(method_ff_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, FunctionDeclarationOutOfLineWithMethodPrototype) {
  TestVerilogSourceFile src(
      "outofline_func.sv",
      "class cc;\n"
      "  extern function int ff(logic ll);\n"  // prototype
      "endclass\n"
      "function int cc::ff(logic ll);\n"  // definition
      "  bit bb;\n"                       // local variable
      "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_ff, class_cc, "ff");
  EXPECT_EQ(method_ff_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(method_ff_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*method_ff_info.declared_type.syntax_origin),
      "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(port_ll, method_ff, "ll");
  EXPECT_EQ(port_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(port_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*port_ll_info.declared_type.syntax_origin),
      "logic");

  MUST_ASSIGN_LOOKUP_SYMBOL(local_bb, method_ff, "bb");
  EXPECT_EQ(local_bb_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(local_bb_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*local_bb_info.declared_type.syntax_origin),
      "bit");

  // out-of-line declaration creates a self-reference.
  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);

  // Method reference is resolved to the injected symbol.
  const ReferenceComponentNode* ff_ref = cc_ref->LastLeaf();
  const ReferenceComponent& ref(ff_ref->Value());
  EXPECT_EQ(ref.identifier, "ff");
  EXPECT_EQ(ref.resolved_symbol, &method_ff);

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());
  EXPECT_TRUE(method_ff_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Already resolved.
    EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);
    EXPECT_EQ(ref.resolved_symbol, &method_ff);
  }
}

TEST(BuildSymbolTableTest, TaskDeclaration) {
  TestVerilogSourceFile src("taskrabbit.sv",
                            "task tt;\n"
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(task_tt, root_symbol, "tt");
  EXPECT_EQ(task_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(task_tt_info.file_origin, &src);
  // no return type
  EXPECT_EQ(task_tt_info.declared_type.syntax_origin, nullptr);

  EXPECT_TRUE(task_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationInPackage) {
  TestVerilogSourceFile src("taskrabbit.sv",
                            "package pp;\n"
                            "task tt();\n"
                            "endtask\n"
                            "endpackage\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  MUST_ASSIGN_LOOKUP_SYMBOL(task_tt, package_pp, "tt");
  EXPECT_EQ(task_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(task_tt_info.file_origin, &src);
  // no return type
  EXPECT_EQ(task_tt_info.declared_type.syntax_origin, nullptr);

  EXPECT_TRUE(task_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationInModule) {
  TestVerilogSourceFile src("taskrabbit.sv",
                            "module mm;\n"
                            "task tt();\n"
                            "endtask\n"
                            "endmodule\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_mm, root_symbol, "mm");
  MUST_ASSIGN_LOOKUP_SYMBOL(task_tt, module_mm, "tt");
  EXPECT_EQ(task_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(task_tt_info.file_origin, &src);
  // no return type
  EXPECT_EQ(task_tt_info.declared_type.syntax_origin, nullptr);

  EXPECT_TRUE(task_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationInClass) {
  TestVerilogSourceFile src("taskrabbit.sv",
                            "class cc;\n"
                            "task tt();\n"
                            "endtask\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(task_tt, class_cc, "tt");
  EXPECT_EQ(task_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(task_tt_info.file_origin, &src);
  // no return type
  EXPECT_EQ(task_tt_info.declared_type.syntax_origin, nullptr);

  EXPECT_TRUE(task_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationWithPorts) {
  TestVerilogSourceFile src("taskrabbit.sv",
                            "task tt(logic ll);\n"
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(task_tt, root_symbol, "tt");
  EXPECT_EQ(task_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(task_tt_info.file_origin, &src);
  // no return type
  EXPECT_EQ(task_tt_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(logic_ll, task_tt, "ll");
  EXPECT_EQ(logic_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(logic_ll_info.file_origin, &src);
  // primitive type
  ASSERT_NE(logic_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*logic_ll_info.declared_type.syntax_origin),
      "logic");

  EXPECT_TRUE(task_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationOutOfLineMissingOuterClass) {
  TestVerilogSourceFile src("outofline_task.sv",
                            "task cc::tt;\n"  // "cc" undeclared
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"cc\" in parent scope (<root>) $root"));
  }

  // out-of-line declaration creates a self-reference.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);

    // Same diagnostic as before.
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"cc\" in parent scope (<root>) $root"));
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationOutOfLineMissingPrototype) {
  TestVerilogSourceFile src("outofline_task.sv",
                            "class cc;\n"
                            // no "tt" prototype
                            "endclass\n"
                            "task cc::tt;\n"
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    // This diagnostic is non-fatal.
    // Expect that "tt" will be injected into "cc" when its method prototype is
    // missing.
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("No member symbol \"tt\" in parent scope (class) cc"));
  }
  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_tt, class_cc, "tt");
  EXPECT_EQ(method_tt_info.metatype, SymbolMetaType::kTask);

  // out-of-line declaration creates a self-reference.
  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);

  // Method reference is resolved to the injected symbol.
  const ReferenceComponentNode* tt_ref = cc_ref->LastLeaf();
  const ReferenceComponent& ref(tt_ref->Value());
  EXPECT_EQ(ref.identifier, "tt");
  EXPECT_EQ(ref.resolved_symbol, &method_tt);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Already resolved before, still remains resolved.
    EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);
    EXPECT_EQ(ref.resolved_symbol, &method_tt);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationOutOfLineInvalidPackageInjection) {
  TestVerilogSourceFile src("outofline_task.sv",
                            "package pp;\n"
                            "endpackage\n"
                            "task pp::tt;\n"
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  {
    // Expect that "tt" will not injected into "pp" because it is a package,
    // not a class.
    ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"pp\" to resolve to a class, "
                          "but found a package"));
  }
  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  EXPECT_EQ(package_pp_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(package_pp.Find("tt"), package_pp.end());

  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_ref, ref_map, "pp");
  EXPECT_EQ(pp_ref->components->Value().resolved_symbol, nullptr);

  // Method injection will not happen for packages.
  const ReferenceComponentNode* tt_ref = pp_ref->LastLeaf();
  const ReferenceComponent& ref(tt_ref->Value());
  EXPECT_EQ(ref.identifier, "tt");
  EXPECT_EQ(ref.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSERT_EQ(resolve_diagnostics.size(), 1);

    // Still remain unresolved.
    EXPECT_EQ(pp_ref->components->Value().resolved_symbol, nullptr);
    EXPECT_EQ(ref.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationMethodPrototypeOnly) {
  TestVerilogSourceFile src("outofline_task.sv",
                            "class cc;\n"
                            "  extern task tt(logic ll);\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_tt, class_cc, "tt");
  EXPECT_EQ(method_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(method_tt_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(port_ll, method_tt, "ll");
  EXPECT_EQ(port_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(port_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*port_ll_info.declared_type.syntax_origin),
      "logic");

  // No references to resolve.
  EXPECT_TRUE(root_symbol.Value().local_references_to_bind.empty());
  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());
  EXPECT_TRUE(method_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);
  }
}

TEST(BuildSymbolTableTest, TaskDeclarationOutOfLineWithMethodPrototype) {
  TestVerilogSourceFile src("outofline_task.sv",
                            "class cc;\n"
                            "  extern task tt(logic ll);\n"  // prototype
                            "endclass\n"
                            "task cc::tt(logic ll);\n"  // definition
                            "  bit bb;\n"               // local variable
                            "endtask\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_tt, class_cc, "tt");
  EXPECT_EQ(method_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(method_tt_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(port_ll, method_tt, "ll");
  EXPECT_EQ(port_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(port_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*port_ll_info.declared_type.syntax_origin),
      "logic");

  MUST_ASSIGN_LOOKUP_SYMBOL(local_bb, method_tt, "bb");
  EXPECT_EQ(local_bb_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(local_bb_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*local_bb_info.declared_type.syntax_origin),
      "bit");

  // out-of-line declaration creates a self-reference.
  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);

  // Method reference is resolved to the injected symbol.
  const ReferenceComponentNode* tt_ref = cc_ref->LastLeaf();
  const ReferenceComponent& ref(tt_ref->Value());
  EXPECT_EQ(ref.identifier, "tt");
  EXPECT_EQ(ref.resolved_symbol, &method_tt);

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());
  EXPECT_TRUE(method_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Already resolved.
    EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);
    EXPECT_EQ(ref.resolved_symbol, &method_tt);
  }
}

TEST(BuildSymbolTableTest, OutOfLineDefinitionMismatchesPrototype) {
  TestVerilogSourceFile src(
      "outofline_task_or_func.sv",
      "class cc;\n"
      "  extern task tt(logic ll);\n"  // task prototype
      "endclass\n"
      "function int cc::tt(logic ll);\n"  // function definition (wrong type)
      "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  ASSIGN_MUST_HAVE_UNIQUE(err, build_diagnostics);
  EXPECT_EQ(err.code(), absl::StatusCode::kAlreadyExists);
  EXPECT_THAT(
      err.message(),
      HasSubstr(
          "task $root::cc::tt cannot be redefined out-of-line as a function"));

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(method_tt, class_cc, "tt");
  EXPECT_EQ(method_tt_info.metatype, SymbolMetaType::kTask);
  EXPECT_EQ(method_tt_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(port_ll, method_tt, "ll");
  EXPECT_EQ(port_ll_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(port_ll_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*port_ll_info.declared_type.syntax_origin),
      "logic");

  // Reference must be resolved at Build-time.
  EXPECT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);

  // Method reference "tt" fails to resolve due to metatype mismatch.
  const ReferenceComponentNode* tt_ref = cc_ref->LastLeaf();
  const ReferenceComponent& ref(tt_ref->Value());
  EXPECT_EQ(ref.identifier, "tt");
  EXPECT_EQ(ref.resolved_symbol, nullptr);

  EXPECT_TRUE(class_cc_info.local_references_to_bind.empty());
  EXPECT_TRUE(method_tt_info.local_references_to_bind.empty());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"tt\" to resolve to a "
                          "function, but found a task"));

    EXPECT_EQ(cc_ref->components->Value().resolved_symbol, &class_cc);
    EXPECT_EQ(ref.resolved_symbol, nullptr);  // Still fails to resolve.
  }
}

TEST(BuildSymbolTableTest, FunctionCallResolvedSameScope) {
  TestVerilogSourceFile src("call_me.sv",
                            "function int tt();\n"
                            "  return 1;\n"
                            "endfunction\n"
                            "function int vv();\n"
                            "  return tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, root_symbol, "tt");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to "tt" is resolved.
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, FunctionCallUnresolved) {
  TestVerilogSourceFile src("call_me_not.sv",
                            "function int vv();\n"
                            "  return tt();\n"  // undefined
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("Unable to resolve symbol \"tt\" from context $root::vv"));

    // Call to "tt" is unresolved.
    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, FunctionCallUnresolvedNamedParameters) {
  TestVerilogSourceFile src("call_me_not.sv",
                            "function int vv();\n"
                            "  return tt(.a(1), .b(2));\n"  // undefined
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentMap param_refs(
      ReferenceComponentNodeMapView(*tt_ref->components));

  ASSIGN_MUST_FIND(a_ref, param_refs, "a");
  const ReferenceComponent& a_ref_comp(a_ref->Value());
  EXPECT_EQ(a_ref_comp.identifier, "a");
  EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(a_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(a_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(b_ref, param_refs, "b");
  const ReferenceComponent& b_ref_comp(b_ref->Value());
  EXPECT_EQ(b_ref_comp.identifier, "b");
  EXPECT_EQ(b_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(b_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(b_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);
    EXPECT_THAT(
        err.message(),
        HasSubstr("Unable to resolve symbol \"tt\" from context $root::vv"));

    // Call to "tt" is unresolved, as are its named parameters.
    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);
    EXPECT_EQ(a_ref_comp.resolved_symbol, nullptr);  // not yet resolved
    EXPECT_EQ(b_ref_comp.resolved_symbol, nullptr);  // not yet resolved
  }
}

TEST(BuildSymbolTableTest, FunctionCallResolvedNamedParameters) {
  TestVerilogSourceFile src("call_me_not.sv",
                            "function int tt(int a, int b);\n"
                            "  return 0;\n"
                            "endfunction\n"
                            "function int vv();\n"
                            "  return tt(.a(1), .b(2));\n"  // valid
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, root_symbol, "tt");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin,
            nullptr);  // returns int

  MUST_ASSIGN_LOOKUP_SYMBOL(param_a, function_tt, "a");
  EXPECT_EQ(param_a_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(param_a_info.declared_type.syntax_origin, nullptr);  // int a

  MUST_ASSIGN_LOOKUP_SYMBOL(param_b, function_tt, "b");
  EXPECT_EQ(param_b_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  ASSERT_NE(param_b_info.declared_type.syntax_origin, nullptr);  // int b

  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentMap param_refs(
      ReferenceComponentNodeMapView(*tt_ref->components));

  ASSIGN_MUST_FIND(a_ref, param_refs, "a");
  const ReferenceComponent& a_ref_comp(a_ref->Value());
  EXPECT_EQ(a_ref_comp.identifier, "a");
  EXPECT_EQ(a_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(a_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(a_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  ASSIGN_MUST_FIND(b_ref, param_refs, "b");
  const ReferenceComponent& b_ref_comp(b_ref->Value());
  EXPECT_EQ(b_ref_comp.identifier, "b");
  EXPECT_EQ(b_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(b_ref_comp.required_metatype,
            SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(b_ref_comp.resolved_symbol, nullptr);  // not yet resolved

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to "tt" is resolved, along with its named parameters.
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
    EXPECT_EQ(a_ref_comp.resolved_symbol, &param_a);
    EXPECT_EQ(b_ref_comp.resolved_symbol, &param_b);
  }
}

TEST(BuildSymbolTableTest, CallNonFunction) {
  TestVerilogSourceFile src("call_me.sv",
                            "module tt();\n"
                            "endmodule\n"
                            "function int vv();\n"
                            "  return tt();\n"  // not a function
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(module_tt, root_symbol, "tt");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(module_tt_info.metatype, SymbolMetaType::kModule);
  EXPECT_EQ(module_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  EXPECT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(),
                HasSubstr("Expecting reference \"tt\" to resolve to a "
                          "<callable>, but found a module"));

    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);
  }
}

TEST(BuildSymbolTableTest, NestedCallsArguments) {
  TestVerilogSourceFile src("call_me.sv",
                            "function int tt(int aa);\n"
                            "  return aa + 1;\n"
                            "endfunction\n"
                            "function int vv();\n"
                            "  return tt(tt(tt(2)));\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, root_symbol, "tt");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(arg_aa, function_tt, "aa");
  EXPECT_EQ(arg_aa_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  EXPECT_EQ(function_tt_info.local_references_to_bind.size(), 1);
  const auto tt_ref_map(function_tt_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(aa_ref, tt_ref_map, "aa");
  const ReferenceComponent& aa_ref_comp(aa_ref->components->Value());
  EXPECT_EQ(aa_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(aa_ref_comp.resolved_symbol, nullptr);

  // Expect 3 calls to "tt" from the same scope.
  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 3);
  const auto vv_ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(tt_refs, vv_ref_map, "tt");
  for (const auto& tt_ref : tt_refs) {
    const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
    EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);
  }

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(aa_ref_comp.resolved_symbol, &arg_aa);

    // Calls to "tt" are all resolved.
    for (const auto& tt_ref : tt_refs) {
      const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
      EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
    }
  }
}

TEST(BuildSymbolTableTest, SelfRecursion) {
  TestVerilogSourceFile src("call_me_from_me.sv",
                            "function int tt();\n"
                            "  return 1 - tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, root_symbol, "tt");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_tt_info.local_references_to_bind.size(), 1);
  const auto tt_ref_map(function_tt_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, tt_ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to "tt" (recursive) is resolved.
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, MutualRecursion) {
  TestVerilogSourceFile src("call_me_back.sv",
                            "function int tt();\n"
                            "  return vv();\n"
                            "endfunction\n"
                            "function int vv();\n"
                            "  return tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, root_symbol, "tt");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_tt_info.local_references_to_bind.size(), 1);
  const auto tt_ref_map(function_tt_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(vv_ref, tt_ref_map, "vv");
  const ReferenceComponent& vv_ref_comp(vv_ref->components->Value());
  EXPECT_EQ(vv_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(vv_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto vv_ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(tt_ref, vv_ref_map, "tt");
  const ReferenceComponent& tt_ref_comp(tt_ref->components->Value());
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Calls to "tt" and "vv" are all resolved.
    EXPECT_EQ(vv_ref_comp.resolved_symbol, &function_vv);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, PackageQualifiedFunctionCall) {
  TestVerilogSourceFile src("call_me.sv",
                            "package pp;\n"
                            "  function int tt();\n"
                            "    return 1;\n"
                            "  endfunction\n"
                            "endpackage\n"
                            "function int vv();\n"
                            "  return pp::tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, package_pp, "tt");
  EXPECT_EQ(package_pp_info.metatype, SymbolMetaType::kPackage);
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_ref, ref_map, "pp");
  ASSERT_EQ(pp_ref->components->Children().size(), 1);
  const ReferenceComponent& pp_ref_comp(pp_ref->components->Value());
  EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponent& tt_ref_comp(
      pp_ref->components->Children().front().Value());
  EXPECT_EQ(tt_ref_comp.identifier, "tt");
  EXPECT_EQ(tt_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to "tt" is resolved.
    EXPECT_EQ(pp_ref_comp.resolved_symbol, &package_pp);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, ClassQualifiedFunctionCall) {
  TestVerilogSourceFile src("call_me.sv",
                            "class cc;\n"
                            "  function static int tt();\n"
                            "    return 1;\n"
                            "  endfunction\n"
                            "endclass\n"
                            "function int vv();\n"
                            "  return cc::tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, class_cc, "tt");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  ASSERT_EQ(cc_ref->components->Children().size(), 1);
  const ReferenceComponent& cc_ref_comp(cc_ref->components->Value());
  EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponent& tt_ref_comp(
      cc_ref->components->Children().front().Value());
  EXPECT_EQ(tt_ref_comp.identifier, "tt");
  EXPECT_EQ(tt_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to "tt" is resolved.
    EXPECT_EQ(cc_ref_comp.resolved_symbol, &class_cc);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, ClassQualifiedFunctionCallUnresolved) {
  TestVerilogSourceFile src("call_me.sv",
                            "class cc;\n"
                            "endclass\n"
                            "function int vv();\n"
                            "  return cc::tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 1);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_ref, ref_map, "cc");
  ASSERT_EQ(cc_ref->components->Children().size(), 1);
  const ReferenceComponent& cc_ref_comp(cc_ref->components->Value());
  EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponent& tt_ref_comp(
      cc_ref->components->Children().front().Value());
  EXPECT_EQ(tt_ref_comp.identifier, "tt");
  EXPECT_EQ(tt_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);

    EXPECT_EQ(cc_ref_comp.resolved_symbol, &class_cc);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);  // error
  }
}

TEST(BuildSymbolTableTest, ClassMethodCall) {
  TestVerilogSourceFile src("call_me.sv",
                            "class cc;\n"
                            "  function int tt();\n"
                            "    return 1;\n"
                            "  endfunction\n"
                            "endclass\n"
                            "function int vv();\n"
                            "  cc cc_obj;\n"
                            "  return cc_obj.tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, class_cc, "tt");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);
  MUST_ASSIGN_LOOKUP_SYMBOL(cc_obj, function_vv, "cc_obj");
  EXPECT_EQ(cc_obj_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 2);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_type_ref, ref_map,
                                   "cc");  // "cc" is a type
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref->components->Value());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_obj_ref, ref_map,
                                   "cc_obj");  // "cc_obj" is data
  ASSERT_EQ(cc_obj_ref->components->Children().size(), 1);
  const ReferenceComponent& cc_obj_ref_comp(cc_obj_ref->components->Value());
  EXPECT_EQ(cc_obj_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_obj_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_obj_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponent& tt_ref_comp(
      cc_obj_ref->components->Children().front().Value());
  EXPECT_EQ(tt_ref_comp.identifier, "tt");
  EXPECT_EQ(tt_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Call to ".tt" is resolved.
    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, &class_cc);
    EXPECT_EQ(cc_obj_ref_comp.resolved_symbol, &cc_obj);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, ClassMethodCallUnresolved) {
  TestVerilogSourceFile src("call_me.sv",
                            "class cc;\n"
                            "endclass\n"
                            "function int vv();\n"
                            "  cc cc_obj;\n"
                            "  return cc_obj.tt();\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);
  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);
  MUST_ASSIGN_LOOKUP_SYMBOL(cc_obj, function_vv, "cc_obj");
  EXPECT_EQ(cc_obj_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 2);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_type_ref, ref_map,
                                   "cc");  // "cc" is a type
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref->components->Value());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(cc_obj_ref, ref_map,
                                   "cc_obj");  // "cc_obj" is data
  ASSERT_EQ(cc_obj_ref->components->Children().size(), 1);
  const ReferenceComponent& cc_obj_ref_comp(cc_obj_ref->components->Value());
  EXPECT_EQ(cc_obj_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_obj_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_obj_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponent& tt_ref_comp(
      cc_obj_ref->components->Children().front().Value());
  EXPECT_EQ(tt_ref_comp.identifier, "tt");
  EXPECT_EQ(tt_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);

    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, &class_cc);
    EXPECT_EQ(cc_obj_ref_comp.resolved_symbol, &cc_obj);
    EXPECT_EQ(tt_ref_comp.resolved_symbol, nullptr);  // unresolved
  }
}

TEST(BuildSymbolTableTest, ChainedMethodCall) {
  TestVerilogSourceFile src("call_me.sv",
                            "class cc;\n"
                            "  function dd tt();\n"
                            "  endfunction\n"
                            "endclass\n"
                            "class dd;\n"
                            "  function cc gg();\n"
                            "  endfunction\n"
                            "endclass\n"
                            "function dd vv();\n"
                            "  dd dd_obj;\n"
                            "  return dd_obj.gg().tt();\n"
                            // .gg() -> cc
                            // .tt() -> dd
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_dd, root_symbol, "dd");
  EXPECT_EQ(class_dd_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, class_cc, "tt");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  ASSERT_NE(function_tt_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_gg, class_dd, "gg");
  EXPECT_EQ(function_gg_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_gg_info.declared_type.syntax_origin, nullptr);
  ASSERT_NE(function_gg_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(dd_obj, function_vv, "dd_obj");
  EXPECT_EQ(dd_obj_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 2);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_type_ref, ref_map,
                                   "dd");  // "dd" is a type
  const ReferenceComponent& dd_type_ref_comp(dd_type_ref->components->Value());

  // Examine the dd_obj.gg().tt() reference chain.
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_obj_ref, ref_map,
                                   "dd_obj");  // "dd_obj" is data
  ASSERT_EQ(dd_obj_ref->components->Children().size(), 1);
  const ReferenceComponent& dd_obj_ref_comp(dd_obj_ref->components->Value());
  EXPECT_EQ(dd_obj_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(dd_obj_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_obj_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentNode& dd_gg_ref(
      dd_obj_ref->components->Children().front());
  const ReferenceComponent& dd_gg_ref_comp(dd_gg_ref.Value());
  EXPECT_EQ(dd_gg_ref_comp.identifier, "gg");
  EXPECT_EQ(dd_gg_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_gg_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(dd_gg_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentNode& dd_gg_tt_ref(dd_gg_ref.Children().front());
  const ReferenceComponent& dd_gg_tt_ref_comp(dd_gg_tt_ref.Value());
  EXPECT_EQ(dd_gg_tt_ref_comp.identifier, "tt");
  EXPECT_EQ(dd_gg_tt_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_gg_tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(dd_gg_tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Return types of methods are resolved.
    EXPECT_EQ(function_tt_info.declared_type.user_defined_type->Value()
                  .resolved_symbol,
              &class_dd);
    EXPECT_EQ(function_gg_info.declared_type.user_defined_type->Value()
                  .resolved_symbol,
              &class_cc);

    // Chained call is resolved.
    EXPECT_EQ(dd_type_ref_comp.resolved_symbol, &class_dd);
    EXPECT_EQ(dd_obj_ref_comp.resolved_symbol, &dd_obj);
    EXPECT_EQ(dd_gg_ref_comp.resolved_symbol, &function_gg);
    EXPECT_EQ(dd_gg_tt_ref_comp.resolved_symbol, &function_tt);
  }
}

TEST(BuildSymbolTableTest, ChainedMethodCallReturnTypeNotAClass) {
  TestVerilogSourceFile src(
      "call_me.sv",
      "class cc;\n"
      "  function dd tt();\n"
      "  endfunction\n"
      "endclass\n"
      "class dd;\n"
      "  function int gg();\n"  // return type is a primitive
      "  endfunction\n"
      "endclass\n"
      "function dd vv();\n"
      "  dd dd_obj;\n"
      "  return dd_obj.gg().tt();\n"
      // .gg() -> cc
      // .tt() -> <error>
      "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_cc, root_symbol, "cc");
  EXPECT_EQ(class_cc_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(class_dd, root_symbol, "dd");
  EXPECT_EQ(class_dd_info.metatype, SymbolMetaType::kClass);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_tt, class_cc, "tt");
  EXPECT_EQ(function_tt_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_tt_info.declared_type.syntax_origin, nullptr);
  ASSERT_NE(function_tt_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_gg, class_dd, "gg");
  EXPECT_EQ(function_gg_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_gg_info.declared_type.syntax_origin, nullptr);
  EXPECT_EQ(function_gg_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_vv, root_symbol, "vv");
  EXPECT_EQ(function_vv_info.metatype, SymbolMetaType::kFunction);
  ASSERT_NE(function_vv_info.declared_type.syntax_origin, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(dd_obj, function_vv, "dd_obj");
  EXPECT_EQ(dd_obj_info.metatype, SymbolMetaType::kDataNetVariableInstance);

  EXPECT_EQ(function_vv_info.local_references_to_bind.size(), 2);
  const auto ref_map(function_vv_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_type_ref, ref_map,
                                   "dd");  // "dd" is a type
  const ReferenceComponent& dd_type_ref_comp(dd_type_ref->components->Value());

  // Examine the dd_obj.gg().tt() reference chain.
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(dd_obj_ref, ref_map,
                                   "dd_obj");  // "dd_obj" is data
  ASSERT_EQ(dd_obj_ref->components->Children().size(), 1);
  const ReferenceComponent& dd_obj_ref_comp(dd_obj_ref->components->Value());
  EXPECT_EQ(dd_obj_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(dd_obj_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_obj_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentNode& dd_gg_ref(
      dd_obj_ref->components->Children().front());
  const ReferenceComponent& dd_gg_ref_comp(dd_gg_ref.Value());
  EXPECT_EQ(dd_gg_ref_comp.identifier, "gg");
  EXPECT_EQ(dd_gg_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_gg_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(dd_gg_ref_comp.resolved_symbol, nullptr);

  const ReferenceComponentNode& dd_gg_tt_ref(dd_gg_ref.Children().front());
  const ReferenceComponent& dd_gg_tt_ref_comp(dd_gg_tt_ref.Value());
  EXPECT_EQ(dd_gg_tt_ref_comp.identifier, "tt");
  EXPECT_EQ(dd_gg_tt_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(dd_gg_tt_ref_comp.required_metatype, SymbolMetaType::kCallable);
  EXPECT_EQ(dd_gg_tt_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(), HasSubstr("Type of parent reference"));
    // reference text in diagnostic looks like: "@dd_obj.gg[<callable>]"
    EXPECT_THAT(err.message(), HasSubstr("(int) does not have any members"));

    // Return types of methods are resolved (where non-primitive).
    EXPECT_EQ(function_tt_info.declared_type.user_defined_type->Value()
                  .resolved_symbol,
              &class_dd);

    // Chained call is partially resolved.
    EXPECT_EQ(dd_type_ref_comp.resolved_symbol, &class_dd);
    EXPECT_EQ(dd_obj_ref_comp.resolved_symbol, &dd_obj);
    EXPECT_EQ(dd_gg_ref_comp.resolved_symbol, &function_gg);
    EXPECT_EQ(dd_gg_tt_ref_comp.resolved_symbol, nullptr);  // failed to resolve
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeData) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  int size;\n"
                            "} data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous struct definition and reference.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);
  ASSERT_EQ(root_symbol.Children().size(), 2);
  // Find the symbol that is a struct (anon), which is not "data".
  const auto found =
      std::find_if(root_symbol.Children().begin(), root_symbol.Children().end(),
                   [](const SymbolTableNode::key_value_type& p) {
                     return p.first != "data";
                   });
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  // Struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  // Expect to bind anonymous struct immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeDataMultiFields) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  int size;\n"
                            "  real weight;\n"
                            "} data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous struct definition and reference.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);
  ASSERT_EQ(root_symbol.Children().size(), 2);
  // Find the symbol that is a struct (anon), which is not "data".
  const auto found =
      std::find_if(root_symbol.Children().begin(), root_symbol.Children().end(),
                   [](const SymbolTableNode::key_value_type& p) {
                     return p.first != "data";
                   });
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  // Struct has two members.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(int_weight, anon_struct, "weight");
  EXPECT_EQ(int_weight_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_weight_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_weight_info.declared_type.syntax_origin),
      "real");
  EXPECT_EQ(int_weight_info.declared_type.user_defined_type, nullptr);

  // Expect to bind anonymous struct immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeDataMultiDeclaration) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  int size, weight;\n"
                            // Note: the syntax tree structure for "weight"
                            // looks different than that of the the first
                            // variable "size". Make sure this test continues to
                            // work after CST restructuring.
                            "} data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous struct definition and reference.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);
  ASSERT_EQ(root_symbol.Children().size(), 2);
  // Find the symbol that is a struct (anon), which is not "data".
  const auto found =
      std::find_if(root_symbol.Children().begin(), root_symbol.Children().end(),
                   [](const SymbolTableNode::key_value_type& p) {
                     return p.first != "data";
                   });
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  // Struct has two members.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(int_weight, anon_struct, "weight");
  EXPECT_EQ(int_weight_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_weight_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_weight_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_weight_info.declared_type.user_defined_type, nullptr);

  // Expect to bind anonymous struct immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeDataMultiVariables) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  int size;\n"
                            "} data, foobar;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous struct definition and two type references.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);
  ASSERT_EQ(root_symbol.Children().size(), 3);
  // Find the first symbol that is a struct (anon).
  const auto found = std::find_if(
      root_symbol.Children().begin(), root_symbol.Children().end(),
      [](const SymbolTableNode::key_value_type& p) {
        return p.second.Value().metatype == SymbolMetaType::kStruct;
      });
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  // Struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  // Expect to bind anonymous struct immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  // "foobar" has same anonymous struct type
  MUST_ASSIGN_LOOKUP_SYMBOL(foobar, root_symbol, "foobar");
  EXPECT_EQ(foobar_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foobar_info.file_origin, &src);
  EXPECT_EQ(foobar_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // "data" and "foobar" share the same anonymous struct type.
    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &anon_struct);
    EXPECT_EQ(
        foobar_info.declared_type.user_defined_type->Value().resolved_symbol,
        &anon_struct);
  }
}

static bool IsStruct(const SymbolTableNode::key_value_type& p) {
  return p.second.Value().metatype == SymbolMetaType::kStruct;
}

TEST(BuildSymbolTableTest, AnonymousStructTypeDataMultiVariablesDistinctTypes) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  int size;\n"
                            "} data;\n"
                            "struct {\n"
                            "  int size;\n"
                            "} foobar;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect two anonymous struct definitions and two type references.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 2);
  ASSERT_EQ(root_symbol.Children().size(), 4);
  // Find the symbol that is a struct (anon).
  const auto found = std::find_if(root_symbol.Children().begin(),
                                  root_symbol.Children().end(), IsStruct);
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  const auto found_2 =
      std::find_if(std::next(found), root_symbol.Children().end(), IsStruct);
  ASSERT_NE(found_2, root_symbol.Children().end());
  const SymbolTableNode& anon_struct_2(found_2->second);
  const SymbolInfo& anon_struct_2_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_2_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_2_info.local_references_to_bind.empty());

  // Struct has one member.  Both structs have the same elements and structure,
  // but have distinct scopes in the symbol table.
  for (const auto* anon_struct_iter : {&anon_struct, &anon_struct_2}) {
    MUST_ASSIGN_LOOKUP_SYMBOL(int_size, *anon_struct_iter, "size");
    EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
    EXPECT_EQ(int_size_info.file_origin, &src);
    EXPECT_EQ(
        verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
        "int");
    EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);
  }

  // Expect to bind both anonymous structs immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 2);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  const DependentReferences& anon_struct_2_ref(
      root_symbol.Value().local_references_to_bind.back());
  const ReferenceComponent& anon_struct_2_ref_comp(
      anon_struct_2_ref.components->Value());
  EXPECT_EQ(anon_struct_2_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_2_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_2_ref_comp.resolved_symbol, &anon_struct_2);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  // "foobar" has a different anonymous struct type
  MUST_ASSIGN_LOOKUP_SYMBOL(foobar, root_symbol, "foobar");
  EXPECT_EQ(foobar_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foobar_info.file_origin, &src);
  EXPECT_EQ(foobar_info.declared_type.user_defined_type,
            anon_struct_2_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // "data" and "foobar" have different anonymous struct types.
    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
    EXPECT_EQ(anon_struct_2_ref_comp.resolved_symbol,
              &anon_struct_2);  // unchanged
    EXPECT_EQ(
        data_info.declared_type.user_defined_type->Value().resolved_symbol,
        &anon_struct);
    EXPECT_EQ(
        foobar_info.declared_type.user_defined_type->Value().resolved_symbol,
        &anon_struct_2);
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeFunctionParameter) {
  TestVerilogSourceFile src("structy_funky.sv",
                            "function int ff(struct {\n"
                            "      int weight;\n"
                            "    } data);\n"
                            "  return data.weight;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(ff_function, root_symbol, "ff");
  EXPECT_EQ(ff_function_info.metatype, SymbolMetaType::kFunction);

  // Expect one anonymous struct definition and reference.
  EXPECT_EQ(ff_function_info.anonymous_scope_names.size(), 1);
  ASSERT_EQ(ff_function.Children().size(), 2);
  // Find the symbol that is a struct (anon).
  const auto found = std::find_if(
      ff_function.Children().begin(), ff_function.Children().end(),
      [](const SymbolTableNode::key_value_type& p) {
        return p.second.Value().metatype == SymbolMetaType::kStruct;
      });
  ASSERT_NE(found, ff_function.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_weight, anon_struct, "weight");
  EXPECT_EQ(int_weight_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_weight_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_weight_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_weight_info.declared_type.user_defined_type, nullptr);

  // Expect to bind anonymous struct immediately.
  const auto ref_map(ff_function_info.LocalReferencesMapViewForTesting());
  // Expect one type reference and one reference rooted at "data".
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(data_ref, ref_map, "data");
  const ReferenceComponent& data_ref_comp(data_ref->components->Value());
  EXPECT_EQ(data_ref_comp.identifier, "data");
  EXPECT_EQ(data_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(data_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(data_ref_comp.resolved_symbol, nullptr);

  // "data.weight"
  ASSIGN_MUST_HAVE_UNIQUE(weight_ref, data_ref->components->Children());
  const ReferenceComponent& weight_ref_comp(weight_ref.Value());
  EXPECT_EQ(weight_ref_comp.identifier, "weight");
  EXPECT_EQ(weight_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(weight_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(weight_ref_comp.resolved_symbol, nullptr);

  const DependentReferences& anon_struct_ref(
      **std::find_if(ref_map.begin(), ref_map.end(),
                     [](const decltype(ref_map)::value_type& r) {
                       return (*r.second.begin())
                                  ->components->Value()
                                  .required_metatype == SymbolMetaType::kStruct;
                     })
            ->second.begin());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, ff_function, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(data_ref_comp.resolved_symbol, &data);          // "data"
    EXPECT_EQ(weight_ref_comp.resolved_symbol, &int_weight);  // ".weight"
    EXPECT_EQ(data_info.declared_type.user_defined_type,
              anon_struct_ref.LastLeaf());
    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &anon_struct);  // unchanged
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeNested) {
  TestVerilogSourceFile src("structy.sv",
                            "struct {\n"
                            "  struct {\n"
                            "    int size;\n"
                            "  } foo;\n"
                            "} data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous struct definition and reference at root level.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);
  ASSERT_EQ(root_symbol.Children().size(), 2);
  // Find the symbol that is a struct (anon), which is not "data".
  const auto outer_found = std::find_if(root_symbol.Children().begin(),
                                        root_symbol.Children().end(), IsStruct);
  ASSERT_NE(outer_found, root_symbol.Children().end());
  const SymbolTableNode& outer_anon_struct(outer_found->second);
  const SymbolInfo& outer_anon_struct_info(outer_anon_struct.Value());
  EXPECT_EQ(outer_anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(outer_anon_struct_info.local_references_to_bind.size(), 1);
  // Expect one anonymous struct definition inside the outer struct.
  EXPECT_EQ(outer_anon_struct_info.anonymous_scope_names.size(), 1);

  // Outer struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(struct_foo, outer_anon_struct, "foo");
  EXPECT_TRUE(struct_foo.Children().empty());
  EXPECT_EQ(struct_foo_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(struct_foo_info.file_origin, &src);
  EXPECT_NE(struct_foo_info.declared_type.syntax_origin, nullptr);

  // Inner struct lives in the scope of the outer struct.
  const auto inner_found =
      std::find_if(outer_anon_struct.Children().begin(),
                   outer_anon_struct.Children().end(), IsStruct);
  ASSERT_NE(inner_found, outer_anon_struct.Children().end());
  const SymbolTableNode& inner_anon_struct(inner_found->second);
  const SymbolInfo& inner_anon_struct_info(inner_anon_struct.Value());
  EXPECT_EQ(inner_anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(inner_anon_struct_info.local_references_to_bind.empty());

  // "foo"'s type is pre-bound to the inner anonymous struct.
  const ReferenceComponentNode* foo_type =
      struct_foo_info.declared_type.user_defined_type;
  ASSERT_NE(foo_type, nullptr);
  const ReferenceComponent& foo_type_comp(foo_type->Value());
  EXPECT_EQ(foo_type_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(foo_type_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(foo_type_comp.resolved_symbol, &inner_anon_struct);

  // Inner struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, inner_anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  // Expect to bind (outer) anonymous struct immediately.
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 1);
  const DependentReferences& anon_struct_ref(
      root_symbol.Value().local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &outer_anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // No change, anonymous types were already bound.
    EXPECT_EQ(foo_type_comp.resolved_symbol, &inner_anon_struct);
    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &outer_anon_struct);
  }
}

TEST(BuildSymbolTableTest, AnonymousStructTypeNestedMemberReference) {
  TestVerilogSourceFile src("funky_structy.sv",
                            "function int ff();\n"
                            "  struct {\n"
                            "    struct {\n"
                            "      int size;\n"
                            "    } foo;\n"
                            "  } data;\n"
                            "  return data.foo.size;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(function_ff, root_symbol, "ff");
  EXPECT_EQ(function_ff_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(function_ff_info.file_origin, &src);

  // Expect one anonymous struct definition and reference in function.
  EXPECT_EQ(function_ff_info.anonymous_scope_names.size(), 1);
  ASSERT_EQ(function_ff.Children().size(), 2);
  // Find the symbol that is a struct (anon), which is not "data".
  const auto outer_found = std::find_if(function_ff.Children().begin(),
                                        function_ff.Children().end(), IsStruct);
  ASSERT_NE(outer_found, function_ff.Children().end());
  const SymbolTableNode& outer_anon_struct(outer_found->second);
  const SymbolInfo& outer_anon_struct_info(outer_anon_struct.Value());
  EXPECT_EQ(outer_anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(outer_anon_struct_info.local_references_to_bind.size(), 1);
  // Expect one anonymous struct definition inside the outer struct.
  EXPECT_EQ(outer_anon_struct_info.anonymous_scope_names.size(), 1);

  // Outer struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(struct_foo, outer_anon_struct, "foo");
  EXPECT_TRUE(struct_foo.Children().empty());
  EXPECT_EQ(struct_foo_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(struct_foo_info.file_origin, &src);
  EXPECT_NE(struct_foo_info.declared_type.syntax_origin, nullptr);

  // Inner struct lives in the scope of the outer struct.
  const auto inner_found =
      std::find_if(outer_anon_struct.Children().begin(),
                   outer_anon_struct.Children().end(), IsStruct);
  ASSERT_NE(inner_found, outer_anon_struct.Children().end());
  const SymbolTableNode& inner_anon_struct(inner_found->second);
  const SymbolInfo& inner_anon_struct_info(inner_anon_struct.Value());
  EXPECT_EQ(inner_anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(inner_anon_struct_info.local_references_to_bind.empty());

  // "foo"'s type is pre-bound to the inner anonymous struct.
  const ReferenceComponentNode* foo_type =
      struct_foo_info.declared_type.user_defined_type;
  ASSERT_NE(foo_type, nullptr);
  const ReferenceComponent& foo_type_comp(foo_type->Value());
  EXPECT_EQ(foo_type_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(foo_type_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(foo_type_comp.resolved_symbol, &inner_anon_struct);

  // Inner struct has one member.
  MUST_ASSIGN_LOOKUP_SYMBOL(int_size, inner_anon_struct, "size");
  EXPECT_EQ(int_size_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_size_info.file_origin, &src);
  EXPECT_EQ(
      verible::StringSpanOfSymbol(*int_size_info.declared_type.syntax_origin),
      "int");
  EXPECT_EQ(int_size_info.declared_type.user_defined_type, nullptr);

  // Expect to bind (outer) anonymous struct immediately.
  // First reference to anonymous struct, second reference to "data".
  ASSERT_EQ(function_ff_info.local_references_to_bind.size(), 2);

  const DependentReferences& anon_struct_ref(
      function_ff_info.local_references_to_bind.front());
  const ReferenceComponent& anon_struct_ref_comp(
      anon_struct_ref.components->Value());
  EXPECT_EQ(anon_struct_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_struct_ref_comp.required_metatype, SymbolMetaType::kStruct);
  EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &outer_anon_struct);

  // "data"'s type is the (internal) anonymous struct type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, function_ff, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_struct_ref.LastLeaf());

  // Find the "data.foo.size" reference
  const DependentReferences& data_ref(
      function_ff_info.local_references_to_bind.back());
  const ReferenceComponent& data_ref_comp(data_ref.components->Value());
  EXPECT_EQ(data_ref_comp.identifier, "data");
  EXPECT_EQ(data_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(data_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(data_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(data_foo_ref, data_ref.components->Children());
  const ReferenceComponent& data_foo_ref_comp(data_foo_ref.Value());
  EXPECT_EQ(data_foo_ref_comp.identifier, "foo");
  EXPECT_EQ(data_foo_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(data_foo_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(data_foo_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(data_foo_size_ref, data_foo_ref.Children());
  const ReferenceComponent& data_foo_size_ref_comp(data_foo_size_ref.Value());
  EXPECT_EQ(data_foo_size_ref_comp.identifier, "size");
  EXPECT_EQ(data_foo_size_ref_comp.ref_type,
            ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(data_foo_size_ref_comp.required_metatype,
            SymbolMetaType::kUnspecified);
  EXPECT_EQ(data_foo_size_ref_comp.resolved_symbol, nullptr);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(foo_type_comp.resolved_symbol, &inner_anon_struct);
    EXPECT_EQ(anon_struct_ref_comp.resolved_symbol, &outer_anon_struct);
    // Resolve the reference chain "data.foo.size".
    EXPECT_EQ(data_ref_comp.resolved_symbol, &data);
    EXPECT_EQ(data_foo_ref_comp.resolved_symbol, &struct_foo);
    EXPECT_EQ(data_foo_size_ref_comp.resolved_symbol, &int_size);
  }
}

TEST(BuildSymbolTableTest, AnonymousEnumTypeData) {
  TestVerilogSourceFile src("simple_enum.sv",
                            "enum {\n"
                            "  idle, busy\n"
                            "} data;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Expect one anonymous enum definition and reference.
  EXPECT_EQ(root_symbol.Value().anonymous_scope_names.size(), 1);

  // Expect four symbols (enum, data, idle, busy)
  ASSERT_EQ(root_symbol.Children().size(), 4);

  // Find the symbol that is a enum (anon)
  const auto found = std::find_if(
      root_symbol.Children().begin(), root_symbol.Children().end(),
      [](const SymbolTableNode::key_value_type& p) {
        return p.first != "data" && p.first != "idle" && p.first != "busy";
      });
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_enum(found->second);
  const SymbolInfo& anon_enum_info(anon_enum.Value());
  EXPECT_EQ(anon_enum_info.metatype, SymbolMetaType::kEnumType);
  EXPECT_TRUE(anon_enum_info.local_references_to_bind.empty());

  // Enum has two members.
  EXPECT_EQ(anon_enum.Children().size(), 2);

  MUST_ASSIGN_LOOKUP_SYMBOL(idle, anon_enum, "idle");
  EXPECT_EQ(idle_info.metatype, SymbolMetaType::kEnumConstant);
  EXPECT_EQ(idle_info.file_origin, &src);
  EXPECT_EQ(idle_info.declared_type.user_defined_type, nullptr);

  MUST_ASSIGN_LOOKUP_SYMBOL(busy, anon_enum, "busy");
  EXPECT_EQ(busy_info.metatype, SymbolMetaType::kEnumConstant);
  EXPECT_EQ(busy_info.file_origin, &src);
  EXPECT_EQ(busy_info.declared_type.user_defined_type, nullptr);

  // Find idle symbol
  const auto found_enum_idle =
      std::find_if(root_symbol.Children().begin(), root_symbol.Children().end(),
                   [](const SymbolTableNode::key_value_type& p) {
                     return p.first == "idle";
                   });
  ASSERT_NE(found_enum_idle, root_symbol.Children().end());
  const SymbolTableNode& enum_idle(found_enum_idle->second);
  const SymbolInfo& enum_idle_info(enum_idle.Value());
  EXPECT_EQ(enum_idle_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_TRUE(enum_idle_info.local_references_to_bind.empty());

  // Find busy symbol
  const auto found_enum_busy =
      std::find_if(root_symbol.Children().begin(), root_symbol.Children().end(),
                   [](const SymbolTableNode::key_value_type& p) {
                     return p.first == "busy";
                   });
  ASSERT_NE(found_enum_busy, root_symbol.Children().end());
  const SymbolTableNode& enum_busy(found_enum_busy->second);
  const SymbolInfo& enum_busy_info(enum_busy.Value());
  EXPECT_EQ(enum_busy_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_TRUE(enum_busy_info.local_references_to_bind.empty());

  // Three references: data and two enum constants
  ASSERT_EQ(root_symbol.Value().local_references_to_bind.size(), 3);

  // Expect them to bind immediately.

  const ReferenceComponent& anon_enum_ref_comp(
      root_symbol.Value().local_references_to_bind[2].LastLeaf()->Value());
  EXPECT_EQ(anon_enum_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(anon_enum_ref_comp.required_metatype, SymbolMetaType::kEnumType);
  EXPECT_EQ(anon_enum_ref_comp.resolved_symbol, &anon_enum);

  const ReferenceComponent& enum_idle_ref_comp(
      root_symbol.Value().local_references_to_bind[0].LastLeaf()->Value());
  EXPECT_EQ(enum_idle_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(enum_idle_ref_comp.required_metatype,
            SymbolMetaType::kEnumConstant);
  EXPECT_EQ(enum_idle_ref_comp.resolved_symbol, &busy);

  const ReferenceComponent& enum_busy_ref_comp(
      root_symbol.Value().local_references_to_bind[1].LastLeaf()->Value());
  EXPECT_EQ(enum_busy_ref_comp.ref_type, ReferenceType::kImmediate);
  EXPECT_EQ(enum_busy_ref_comp.required_metatype,
            SymbolMetaType::kEnumConstant);
  EXPECT_EQ(enum_busy_ref_comp.resolved_symbol, &idle);

  // "data"'s type is the (internal) anonymous enum type reference.
  MUST_ASSIGN_LOOKUP_SYMBOL(data, root_symbol, "data");
  EXPECT_EQ(data_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(data_info.file_origin, &src);

  const DependentReferences& anon_enum_ref(
      root_symbol.Value().local_references_to_bind[2]);
  EXPECT_EQ(data_info.declared_type.user_defined_type,
            anon_enum_ref.LastLeaf());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Make sure that resolve doesn't change/break anything
    EXPECT_EQ(anon_enum_ref_comp.resolved_symbol, &anon_enum);
    EXPECT_EQ(enum_idle_ref_comp.resolved_symbol, &busy);
    EXPECT_EQ(enum_busy_ref_comp.resolved_symbol, &idle);
  }
}

TEST(BuildSymbolTableTest, TypedefPrimitive) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef int number;\n"
                            "number one = 1;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(one_var, root_symbol, "one");
  EXPECT_EQ(one_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(one_var_info.file_origin, &src);

  // Expect one type reference to "number".
  ASSIGN_MUST_HAVE_UNIQUE(number_ref,
                          root_symbol.Value().local_references_to_bind);
  const ReferenceComponent& number_ref_comp(number_ref.components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(one_var_info.declared_type.user_defined_type,
            number_ref.components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve type "number" to the typedef.
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefTransitive) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef int num;\n"
                            "typedef num number;\n"
                            "number one = 1;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(num_typedef, root_symbol, "num");
  EXPECT_EQ(num_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(num_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(one_var, root_symbol, "one");
  EXPECT_EQ(one_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(one_var_info.file_origin, &src);

  const auto ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());

  // Expect one type reference to "num".
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(num_ref, ref_map, "num");
  const ReferenceComponent& num_ref_comp(num_ref->components->Value());
  EXPECT_EQ(num_ref_comp.identifier, "num");
  EXPECT_EQ(num_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(num_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(num_ref_comp.resolved_symbol, nullptr);

  // Expect one type reference to "number".
  ASSIGN_MUST_FIND_EXACTLY_ONE_REF(number_ref, ref_map, "number");
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type,
            num_ref->components.get());
  EXPECT_EQ(one_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve type "num" to the typedef.
    EXPECT_EQ(num_ref_comp.resolved_symbol, &num_typedef);
    // Resolve type "number" to the typedef.
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefClass) {
  TestVerilogSourceFile src("typedef.sv",
                            "class cc;\n"
                            "endclass\n"
                            "typedef cc number;\n"
                            "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, root_symbol, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  // Expect one type reference to "number", and one to "cc".
  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(cc_type_refs, ref_map, "cc");
  ASSIGN_MUST_HAVE_UNIQUE(cc_type_ref, cc_type_refs);
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref->components->Value());
  EXPECT_EQ(cc_type_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, &cc_class);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefClassPackageQualified) {
  TestVerilogSourceFile src("typedef.sv",
                            "package pp;\n"
                            "  class cc;\n"
                            "  endclass\n"
                            "endpackage\n"
                            "typedef pp::cc number;\n"
                            "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp_package, root_symbol, "pp");
  EXPECT_EQ(pp_package_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(pp_package_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, pp_package, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());

  // Expect one type reference to "pp::cc".
  ASSIGN_MUST_FIND(pp_type_refs, ref_map, "pp");
  ASSIGN_MUST_HAVE_UNIQUE(pp_type_ref, pp_type_refs);
  const ReferenceComponent& pp_type_ref_comp(pp_type_ref->components->Value());
  EXPECT_EQ(pp_type_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(cc_type_ref, pp_type_ref->components->Children());
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref.Value());
  EXPECT_EQ(cc_type_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_type_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(cc_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);

  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(pp_type_ref_comp.resolved_symbol, &pp_package);
    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, &cc_class);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefClassUnresolvedQualifiedReferenceBase) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef pp::cc number;\n"  // unresolved
                            "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());

  // Expect one type reference to "pp::cc".
  ASSIGN_MUST_FIND(pp_type_refs, ref_map, "pp");
  ASSIGN_MUST_HAVE_UNIQUE(pp_type_ref, pp_type_refs);
  const ReferenceComponent& pp_type_ref_comp(pp_type_ref->components->Value());
  EXPECT_EQ(pp_type_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(cc_type_ref, pp_type_ref->components->Children());
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref.Value());
  EXPECT_EQ(cc_type_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_type_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(cc_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);

  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);

    EXPECT_EQ(pp_type_ref_comp.resolved_symbol, nullptr);
    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefClassPartiallyResolvedQualifiedReference) {
  TestVerilogSourceFile src(
      "typedef.sv",
      "package pp;\n"  // empty
      "endpackage\n"
      "typedef pp::cc::dd number;\n"  // unresolved at "cc"
      "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(package_pp, root_symbol, "pp");
  EXPECT_EQ(package_pp_info.metatype, SymbolMetaType::kPackage);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());

  // Expect one type reference to "pp::cc::dd".
  ASSIGN_MUST_FIND(pp_type_refs, ref_map, "pp");
  ASSIGN_MUST_HAVE_UNIQUE(pp_type_ref, pp_type_refs);
  const ReferenceComponent& pp_type_ref_comp(pp_type_ref->components->Value());
  EXPECT_EQ(pp_type_ref_comp.identifier, "pp");
  EXPECT_EQ(pp_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(pp_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(pp_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(cc_type_ref, pp_type_ref->components->Children());
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref.Value());
  EXPECT_EQ(cc_type_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_type_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(cc_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(dd_type_ref, cc_type_ref.Children());
  const ReferenceComponent& dd_type_ref_comp(dd_type_ref.Value());
  EXPECT_EQ(dd_type_ref_comp.identifier, "dd");
  EXPECT_EQ(dd_type_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(dd_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(dd_type_ref_comp.resolved_symbol, nullptr);

  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kNotFound);

    EXPECT_EQ(pp_type_ref_comp.resolved_symbol, &package_pp);
    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);  // chain fails here
    EXPECT_EQ(dd_type_ref_comp.resolved_symbol, nullptr);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefOfClassTypeParameter) {
  TestVerilogSourceFile src("typedef.sv",
                            "class cc #(parameter type T = int);\n"
                            "  typedef T number;\n"
                            "  number foo;\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, root_symbol, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, cc_class, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, cc_class, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  // Expect one type reference to "number", and one to "T".
  const auto& ref_map(cc_class_info.LocalReferencesMapViewForTesting());

  ASSIGN_MUST_FIND(t_type_refs, ref_map, "T");
  ASSIGN_MUST_HAVE_UNIQUE(t_type_ref, t_type_refs);
  const ReferenceComponent& t_type_ref_comp(t_type_ref->components->Value());
  EXPECT_EQ(t_type_ref_comp.identifier, "T");
  EXPECT_EQ(t_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(t_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(t_type_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // "number" is type-aliased to "T"
    EXPECT_EQ(t_type_ref_comp.resolved_symbol, &t_type_param);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefOfParameterizedClassPositionalParams) {
  TestVerilogSourceFile src("typedef.sv",
                            "package pp;\n"
                            "  class cc #(parameter type T = int);\n"
                            "  endclass\n"
                            "endpackage\n"
                            "typedef pp::cc#(pp::cc#(int)) number;\n"
                            "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp_package, root_symbol, "pp");
  EXPECT_EQ(pp_package_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(pp_package_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, pp_package, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  // Expect two type references to "pp::cc".
  ASSIGN_MUST_FIND(pp_refs, ref_map, "pp");
  EXPECT_EQ(pp_refs.size(), 2);
  for (const auto& pp_ref_iter : pp_refs) {
    const ReferenceComponent& pp_ref_comp(pp_ref_iter->components->Value());
    EXPECT_EQ(pp_ref_comp.identifier, "pp");
    EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

    ASSIGN_MUST_HAVE_UNIQUE(cc_ref, pp_ref_iter->components->Children());
    const ReferenceComponent& cc_ref_comp(cc_ref.Value());
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);
  }

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve "pp::cc" type references
    for (const auto& pp_ref_iter : pp_refs) {
      const ReferenceComponent& pp_ref_comp(pp_ref_iter->components->Value());
      EXPECT_EQ(pp_ref_comp.resolved_symbol, &pp_package);

      ASSIGN_MUST_HAVE_UNIQUE(cc_ref, pp_ref_iter->components->Children());
      const ReferenceComponent& cc_ref_comp(cc_ref.Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);
    }
    // Resolve "number" type reference.
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, TypedefOfParameterizedClassNamedParams) {
  TestVerilogSourceFile src("typedef.sv",
                            "package pp;\n"
                            "  class cc #(parameter type T = int);\n"
                            "  endclass\n"
                            "endpackage\n"
                            "typedef pp::cc#(.T(pp::cc#(.T(int)))) number;\n"
                            "number foo;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp_package, root_symbol, "pp");
  EXPECT_EQ(pp_package_info.metatype, SymbolMetaType::kPackage);
  EXPECT_EQ(pp_package_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, pp_package, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(t_type_param, cc_class, "T");
  EXPECT_EQ(t_type_param_info.metatype, SymbolMetaType::kParameter);
  EXPECT_EQ(t_type_param_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, root_symbol, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  const auto& ref_map(root_symbol.Value().LocalReferencesMapViewForTesting());
  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  // Expect two type references to "pp::cc#(.T(...))".
  ASSIGN_MUST_FIND(pp_refs, ref_map, "pp");
  EXPECT_EQ(pp_refs.size(), 2);
  for (const auto& pp_ref_iter : pp_refs) {
    const ReferenceComponent& pp_ref_comp(pp_ref_iter->components->Value());
    EXPECT_EQ(pp_ref_comp.identifier, "pp");
    EXPECT_EQ(pp_ref_comp.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(pp_ref_comp.resolved_symbol, nullptr);

    ASSIGN_MUST_HAVE_UNIQUE(cc_ref, pp_ref_iter->components->Children());
    const ReferenceComponent& cc_ref_comp(cc_ref.Value());
    EXPECT_EQ(cc_ref_comp.identifier, "cc");
    EXPECT_EQ(cc_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(cc_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(cc_ref_comp.resolved_symbol, nullptr);

    ASSIGN_MUST_HAVE_UNIQUE(t_param_ref, cc_ref.Children());
    const ReferenceComponent& t_param_ref_comp(t_param_ref.Value());
    EXPECT_EQ(t_param_ref_comp.identifier, "T");
    EXPECT_EQ(t_param_ref_comp.ref_type, ReferenceType::kDirectMember);
    EXPECT_EQ(t_param_ref_comp.required_metatype, SymbolMetaType::kParameter);
    EXPECT_EQ(t_param_ref_comp.resolved_symbol, nullptr);
  }

  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve "pp::cc#(.T(...))" type references
    for (const auto& pp_ref_iter : pp_refs) {
      const ReferenceComponent& pp_ref_comp(pp_ref_iter->components->Value());
      EXPECT_EQ(pp_ref_comp.resolved_symbol, &pp_package);

      ASSIGN_MUST_HAVE_UNIQUE(cc_ref, pp_ref_iter->components->Children());
      const ReferenceComponent& cc_ref_comp(cc_ref.Value());
      EXPECT_EQ(cc_ref_comp.resolved_symbol, &cc_class);

      ASSIGN_MUST_HAVE_UNIQUE(t_param_ref, cc_ref.Children());
      const ReferenceComponent& t_param_ref_comp(t_param_ref.Value());
      EXPECT_EQ(t_param_ref_comp.resolved_symbol, &t_type_param);
    }
    // Resolve "number" type reference.
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, InvalidMemberLookupOfAliasedType) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef int number;\n"
                            "typedef number::count bar;\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);
  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *number_typedef_info.declared_type.syntax_origin),
            "int");

  // Expect one type reference to "number".
  const auto& get_count_ref_map(
      root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(number_refs, get_count_ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(number_count_ref, number_ref->components->Children());
  const ReferenceComponent& number_count_ref_comp(number_count_ref.Value());
  EXPECT_EQ(number_count_ref_comp.identifier, "count");
  EXPECT_EQ(number_count_ref_comp.ref_type, ReferenceType::kDirectMember);
  EXPECT_EQ(number_count_ref_comp.required_metatype,
            SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_count_ref_comp.resolved_symbol, nullptr);

  // Expect one type reference to "number".
  MUST_ASSIGN_LOOKUP_SYMBOL(bar, root_symbol, "bar");
  EXPECT_EQ(bar_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(bar_info.file_origin, &src);
  // type of "bar" is "number::count"
  EXPECT_EQ(bar_info.declared_type.user_defined_type, &number_count_ref);

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(), HasSubstr("Canonical type of "));
    EXPECT_THAT(err.message(), HasSubstr("does not have any members"));

    // Resolving "number::count" should fail.
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
    EXPECT_EQ(number_count_ref_comp.resolved_symbol, nullptr);  // failed
  }
}

TEST(BuildSymbolTableTest, InvalidMemberLookupOfTypedefPrimitive) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef int number;\n"
                            "function int get_count(number foo);\n"
                            "  return foo.count;\n"  // invalid member
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);
  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type, nullptr);
  EXPECT_EQ(verible::StringSpanOfSymbol(
                *number_typedef_info.declared_type.syntax_origin),
            "int");

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, root_symbol, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(get_count_info.file_origin, &src);
  EXPECT_EQ(get_count_info.declared_type.user_defined_type, nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, get_count, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  // Expect one type reference to "number".
  const auto& get_count_ref_map(
      get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(number_refs, get_count_ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(foo_refs, get_count_ref_map, "foo");
  ASSIGN_MUST_HAVE_UNIQUE(foo_ref, foo_refs);
  const ReferenceComponent& foo_ref_comp(foo_ref->components->Value());
  EXPECT_EQ(foo_ref_comp.identifier, "foo");
  EXPECT_EQ(foo_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(foo_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(foo_count_ref, foo_ref->components->Children());
  const ReferenceComponent& foo_count_ref_comp(foo_count_ref.Value());
  EXPECT_EQ(foo_count_ref_comp.identifier, "count");
  EXPECT_EQ(foo_count_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(foo_count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_count_ref_comp.resolved_symbol, nullptr);

  // type of "foo" is "number"
  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    ASSIGN_MUST_HAVE_UNIQUE(err, resolve_diagnostics);
    EXPECT_EQ(err.code(), absl::StatusCode::kInvalidArgument);
    EXPECT_THAT(err.message(), HasSubstr("Canonical type of "));
    EXPECT_THAT(err.message(), HasSubstr("does not have any members"));

    // Resolve "foo.count" to "cc::count" through typedef "number"
    EXPECT_EQ(foo_ref_comp.resolved_symbol, &foo_var);
    EXPECT_EQ(foo_count_ref_comp.resolved_symbol, nullptr);  // failed
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, AccessClassMemberThroughTypedef) {
  TestVerilogSourceFile src("typedef.sv",
                            "class cc;\n"
                            "  int count;\n"
                            "endclass\n"
                            "typedef cc number;\n"
                            "function int get_count(number foo);\n"
                            "  return foo.count;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(cc_class, root_symbol, "cc");
  EXPECT_EQ(cc_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(cc_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, cc_class, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_count_info.file_origin, &src);
  EXPECT_EQ(int_count_info.declared_type.user_defined_type, nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, root_symbol, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(get_count_info.file_origin, &src);
  EXPECT_EQ(get_count_info.declared_type.user_defined_type, nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, get_count, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  // Expect one type reference to "cc".
  const auto& root_ref_map(
      root_symbol.Value().LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(cc_type_refs, root_ref_map, "cc");
  ASSIGN_MUST_HAVE_UNIQUE(cc_type_ref, cc_type_refs);
  const ReferenceComponent& cc_type_ref_comp(cc_type_ref->components->Value());
  EXPECT_EQ(cc_type_ref_comp.identifier, "cc");
  EXPECT_EQ(cc_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(cc_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(cc_type_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type,
            cc_type_ref->LastTypeComponent());

  // Expect one type reference to "number".
  const auto& get_count_ref_map(
      get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(number_refs, get_count_ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(foo_refs, get_count_ref_map, "foo");
  ASSIGN_MUST_HAVE_UNIQUE(foo_ref, foo_refs);
  const ReferenceComponent& foo_ref_comp(foo_ref->components->Value());
  EXPECT_EQ(foo_ref_comp.identifier, "foo");
  EXPECT_EQ(foo_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(foo_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(foo_count_ref, foo_ref->components->Children());
  const ReferenceComponent& foo_count_ref_comp(foo_count_ref.Value());
  EXPECT_EQ(foo_count_ref_comp.identifier, "count");
  EXPECT_EQ(foo_count_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(foo_count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_count_ref_comp.resolved_symbol, nullptr);

  // type of "foo" is "number"
  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve "foo.count" to "cc::count" through typedef "number"
    EXPECT_EQ(cc_type_ref_comp.resolved_symbol, &cc_class);
    EXPECT_EQ(foo_ref_comp.resolved_symbol, &foo_var);
    EXPECT_EQ(foo_count_ref_comp.resolved_symbol, &int_count);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

TEST(BuildSymbolTableTest, AccessStructMemberThroughTypedef) {
  TestVerilogSourceFile src("typedef.sv",
                            "typedef struct {\n"
                            "  int count;\n"
                            "} number;\n"
                            "function int get_count(number foo);\n"
                            "  return foo.count;\n"
                            "endfunction\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Find the symbol that is a struct (anon).
  const auto found = std::find_if(root_symbol.Children().begin(),
                                  root_symbol.Children().end(), IsStruct);
  ASSERT_NE(found, root_symbol.Children().end());
  const SymbolTableNode& anon_struct(found->second);
  const SymbolInfo& anon_struct_info(anon_struct.Value());
  EXPECT_EQ(anon_struct_info.metatype, SymbolMetaType::kStruct);
  EXPECT_TRUE(anon_struct_info.local_references_to_bind.empty());

  MUST_ASSIGN_LOOKUP_SYMBOL(int_count, anon_struct, "count");
  EXPECT_EQ(int_count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(int_count_info.file_origin, &src);
  EXPECT_EQ(int_count_info.declared_type.user_defined_type, nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, root_symbol, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(get_count, root_symbol, "get_count");
  EXPECT_EQ(get_count_info.metatype, SymbolMetaType::kFunction);
  EXPECT_EQ(get_count_info.file_origin, &src);
  EXPECT_EQ(get_count_info.declared_type.user_defined_type, nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(foo_var, get_count, "foo");
  EXPECT_EQ(foo_var_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(foo_var_info.file_origin, &src);

  // typedef struct is already resolved.
  ASSERT_NE(number_typedef_info.declared_type.user_defined_type, nullptr);
  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type->Value()
                .resolved_symbol,
            &anon_struct);

  // Expect one type reference to "number".
  const auto& get_count_ref_map(
      get_count_info.LocalReferencesMapViewForTesting());
  ASSIGN_MUST_FIND(number_refs, get_count_ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_FIND(foo_refs, get_count_ref_map, "foo");
  ASSIGN_MUST_HAVE_UNIQUE(foo_ref, foo_refs);
  const ReferenceComponent& foo_ref_comp(foo_ref->components->Value());
  EXPECT_EQ(foo_ref_comp.identifier, "foo");
  EXPECT_EQ(foo_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(foo_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_ref_comp.resolved_symbol, nullptr);

  ASSIGN_MUST_HAVE_UNIQUE(foo_count_ref, foo_ref->components->Children());
  const ReferenceComponent& foo_count_ref_comp(foo_count_ref.Value());
  EXPECT_EQ(foo_count_ref_comp.identifier, "count");
  EXPECT_EQ(foo_count_ref_comp.ref_type, ReferenceType::kMemberOfTypeOfParent);
  EXPECT_EQ(foo_count_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(foo_count_ref_comp.resolved_symbol, nullptr);

  // type of "foo" is "number"
  EXPECT_EQ(foo_var_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Resolve "foo.count" to "cc::count" through typedef "number"
    EXPECT_EQ(foo_ref_comp.resolved_symbol, &foo_var);
    EXPECT_EQ(foo_count_ref_comp.resolved_symbol, &int_count);
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}
TEST(BuildSymbolTableTest, InheritBaseClassThroughTypedef) {
  TestVerilogSourceFile src("typedef.sv",
                            "class base;\n"
                            "  typedef int number;\n"
                            "endclass\n"
                            "typedef base base_alias;\n"
                            "class derived extends base_alias;\n"
                            "  number count;\n"
                            "endclass\n");
  const auto status = src.Parse();
  ASSERT_TRUE(status.ok()) << status.message();
  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(base_class, root_symbol, "base");
  EXPECT_EQ(base_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(number_typedef, base_class, "number");
  EXPECT_EQ(number_typedef_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(number_typedef_info.file_origin, &src);
  EXPECT_EQ(number_typedef_info.declared_type.user_defined_type,
            nullptr);  // int

  MUST_ASSIGN_LOOKUP_SYMBOL(base_alias, root_symbol, "base_alias");
  EXPECT_EQ(base_alias_info.metatype, SymbolMetaType::kTypeAlias);
  EXPECT_EQ(base_alias_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(derived_class, root_symbol, "derived");
  EXPECT_EQ(derived_class_info.metatype, SymbolMetaType::kClass);
  EXPECT_EQ(derived_class_info.file_origin, &src);

  MUST_ASSIGN_LOOKUP_SYMBOL(count, derived_class, "count");
  EXPECT_EQ(count_info.metatype, SymbolMetaType::kDataNetVariableInstance);
  EXPECT_EQ(count_info.file_origin, &src);

  const auto& root_ref_map(
      root_symbol.Value().LocalReferencesMapViewForTesting());

  // Expect one reference to "base"
  ASSIGN_MUST_FIND(base_type_refs, root_ref_map, "base");
  ASSIGN_MUST_HAVE_UNIQUE(base_type_ref, base_type_refs);
  const ReferenceComponent& base_type_ref_comp(
      base_type_ref->components->Value());
  EXPECT_EQ(base_type_ref_comp.identifier, "base");
  EXPECT_EQ(base_type_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(base_type_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(base_type_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(base_alias_info.declared_type.user_defined_type,
            base_type_ref->components.get());

  // Expect one reference to "base_alias"
  ASSIGN_MUST_FIND(base_alias_refs, root_ref_map, "base_alias");
  ASSIGN_MUST_HAVE_UNIQUE(base_alias_ref, base_alias_refs);
  const ReferenceComponent& base_alias_ref_comp(
      base_alias_ref->components->Value());
  EXPECT_EQ(base_alias_ref_comp.identifier, "base_alias");
  EXPECT_EQ(base_alias_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(base_alias_ref_comp.required_metatype, SymbolMetaType::kClass);
  EXPECT_EQ(base_alias_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(derived_class_info.parent_type.user_defined_type,
            base_alias_ref->components.get());

  const auto& derived_ref_map(
      derived_class_info.LocalReferencesMapViewForTesting());

  // Expect one type reference to "number".
  ASSIGN_MUST_FIND(number_refs, derived_ref_map, "number");
  ASSIGN_MUST_HAVE_UNIQUE(number_ref, number_refs);
  const ReferenceComponent& number_ref_comp(number_ref->components->Value());
  EXPECT_EQ(number_ref_comp.identifier, "number");
  EXPECT_EQ(number_ref_comp.ref_type, ReferenceType::kUnqualified);
  EXPECT_EQ(number_ref_comp.required_metatype, SymbolMetaType::kUnspecified);
  EXPECT_EQ(number_ref_comp.resolved_symbol, nullptr);

  EXPECT_EQ(count_info.declared_type.user_defined_type,
            number_ref->components.get());

  {
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    EXPECT_EQ(base_type_ref_comp.resolved_symbol, &base_class);
    EXPECT_EQ(base_alias_ref_comp.resolved_symbol, &base_alias);
    // "number" is resolved to "base::number"
    EXPECT_EQ(number_ref_comp.resolved_symbol, &number_typedef);
  }
}

static bool SourceFileLess(const TestVerilogSourceFile* left,
                           const TestVerilogSourceFile* right) {
  return left->ReferencedPath() < right->ReferencedPath();
}

static void SortSourceFiles(
    std::vector<const TestVerilogSourceFile*>* sources) {
  std::sort(sources->begin(), sources->end(), SourceFileLess);
}

static bool PermuteSourceFiles(
    std::vector<const TestVerilogSourceFile*>* sources) {
  return std::next_permutation(sources->begin(), sources->end(),
                               SourceFileLess);
}

TEST(BuildSymbolTableTest, MultiFileModuleInstance) {
  // Linear dependency chain between 3 files.
  TestVerilogSourceFile pp_src("pp.sv",
                               "module pp;\n"
                               "endmodule\n");
  TestVerilogSourceFile qq_src("qq.sv",
                               "module qq;\n"
                               "  pp pp_inst();\n"  // instance
                               "endmodule\n");
  TestVerilogSourceFile ss_src("ss.sv",
                               "module ss;\n"
                               "  qq qq_inst();\n"  // instance
                               "endmodule\n");
  {
    const auto status = pp_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }
  {
    const auto status = qq_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }
  {
    const auto status = ss_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }

  // All permutations of the following file ordering should end up with the
  // same results.
  std::vector<const TestVerilogSourceFile*> ordering(
      {&pp_src, &qq_src, &ss_src});
  // start with the lexicographically "lowest" permutation
  SortSourceFiles(&ordering);
  int count = 0;
  do {
    SymbolTable symbol_table(nullptr);
    const SymbolTableNode& root_symbol(symbol_table.Root());

    for (const auto* src : ordering) {
      const auto build_diagnostics = BuildSymbolTable(*src, &symbol_table);
      EXPECT_EMPTY_STATUSES(build_diagnostics);
    }

    // Goal: resolve the reference of "pp" to this definition node.
    MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

    // Inspect inside the "qq" module definition.
    MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

    MUST_ASSIGN_LOOKUP_SYMBOL(ss, root_symbol, "ss");

    // "pp_inst" is an instance of type "pp"
    MUST_ASSIGN_LOOKUP_SYMBOL(pp_inst, qq, "pp_inst");

    // "qq_inst" is an instance of type "qq"
    MUST_ASSIGN_LOOKUP_SYMBOL(qq_inst, ss, "qq_inst");

    EXPECT_EQ(pp_info.file_origin, &pp_src);
    EXPECT_EQ(qq_info.file_origin, &qq_src);
    EXPECT_EQ(ss_info.file_origin, &ss_src);
    {
      ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
      const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
        const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "pp");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        qq_src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "pp_inst" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_inst_self_ref, ref_map, "pp_inst");
        EXPECT_TRUE(is_leaf(*pp_inst_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(pp_inst_self_ref->components->Value().resolved_symbol,
                  &pp_inst);
      }
    }
    {
      ASSERT_EQ(ss_info.local_references_to_bind.size(), 2);
      const auto ref_map(ss_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_type, ref_map, "qq");
        const ReferenceComponentNode* ref_node = qq_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "qq");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        ss_src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "qq_inst" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_inst_self_ref, ref_map, "qq_inst");
        EXPECT_TRUE(is_leaf(*qq_inst_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(qq_inst_self_ref->components->Value().resolved_symbol,
                  &qq_inst);
      }
    }

    {  // Verify pp_inst's type info
      EXPECT_TRUE(pp_inst_info.local_references_to_bind.empty());
      EXPECT_NE(pp_inst_info.declared_type.user_defined_type, nullptr);
      const ReferenceComponent& pp_type(
          pp_inst_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(pp_type.identifier, "pp");
      EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(pp_inst_info.file_origin, &qq_src);
    }

    {  // Verify qq_inst's type info
      EXPECT_TRUE(qq_inst_info.local_references_to_bind.empty());
      EXPECT_NE(qq_inst_info.declared_type.user_defined_type, nullptr);
      const ReferenceComponent& qq_type(
          qq_inst_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(qq_type.identifier, "qq");
      EXPECT_EQ(qq_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(qq_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(qq_type.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(qq_inst_info.file_origin, &ss_src);
    }

    // Resolve symbols.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Verify that typeof(pp_inst) successfully resolved to module pp.
    EXPECT_EQ(
        pp_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
        &pp);
    // Verify that typeof(qq_inst) successfully resolved to module qq.
    EXPECT_EQ(
        qq_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
        &qq);
    ++count;
  } while (PermuteSourceFiles(&ordering));
  EXPECT_EQ(count, 6);  // make sure we covered all permutations
}

TEST(BuildSymbolTableTest, ModuleInstancesFromProjectOneFileAtATime) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include path */});

  // Linear dependency chain between 3 files.  Order arbitrarily chosen.
  constexpr absl::string_view  //
      text1(
          "module ss;\n"
          "  qq qq_inst();\n"  // instance
          "endmodule\n"),
      text2(
          "module pp;\n"
          "endmodule\n"),
      text3(
          "module qq;\n"
          "  pp pp_inst();\n"  // instance
          "endmodule\n");
  // Write to temporary files.
  const ScopedTestFile file1(sources_dir, text1);
  const ScopedTestFile file2(sources_dir, text2);
  const ScopedTestFile file3(sources_dir, text3);

  // Register files as part of project.
  for (const auto* file : {&file1, &file2, &file3}) {
    const auto status_or_file =
        project.OpenTranslationUnit(Basename(file->filename()));
    ASSERT_TRUE(status_or_file.ok());
  }

  SymbolTable symbol_table(&project);
  EXPECT_EQ(symbol_table.Project(), &project);

  // Caller decides order of processing files, which doesn't matter for this
  // example.
  std::vector<absl::Status> build_diagnostics;
  for (const auto* file : {&file3, &file2, &file1}) {
    symbol_table.BuildSingleTranslationUnit(Basename(file->filename()),
                                            &build_diagnostics);
    EXPECT_EMPTY_STATUSES(build_diagnostics);
  }

  const SymbolTableNode& root_symbol(symbol_table.Root());

  // Goal: resolve the reference of "pp" to this definition node.
  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

  // Inspect inside the "qq" module definition.
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

  MUST_ASSIGN_LOOKUP_SYMBOL(ss, root_symbol, "ss");

  // "pp_inst" is an instance of type "pp"
  MUST_ASSIGN_LOOKUP_SYMBOL(pp_inst, qq, "pp_inst");

  // "qq_inst" is an instance of type "qq"
  MUST_ASSIGN_LOOKUP_SYMBOL(qq_inst, ss, "qq_inst");

  {
    ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
    const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
      const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "pp");
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "pp_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_inst_self_ref, ref_map, "pp_inst");
      EXPECT_TRUE(is_leaf(*pp_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(pp_inst_self_ref->components->Value().resolved_symbol,
                &pp_inst);
    }
  }
  {
    ASSERT_EQ(ss_info.local_references_to_bind.size(), 2);
    const auto ref_map(ss_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_type, ref_map, "qq");
      const ReferenceComponentNode* ref_node = qq_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "qq");
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "qq_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_inst_self_ref, ref_map, "qq_inst");
      EXPECT_TRUE(is_leaf(*qq_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(qq_inst_self_ref->components->Value().resolved_symbol,
                &qq_inst);
    }
  }

  {  // Verify pp_inst's type info
    EXPECT_TRUE(pp_inst_info.local_references_to_bind.empty());
    EXPECT_NE(pp_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& pp_type(
        pp_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(pp_type.identifier, "pp");
    EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
  }

  {  // Verify qq_inst's type info
    EXPECT_TRUE(qq_inst_info.local_references_to_bind.empty());
    EXPECT_NE(qq_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& qq_type(
        qq_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(qq_type.identifier, "qq");
    EXPECT_EQ(qq_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(qq_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(qq_type.required_metatype, SymbolMetaType::kUnspecified);
  }

  // Resolve symbols.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);

  // Verify that typeof(pp_inst) successfully resolved to module pp.
  EXPECT_EQ(
      pp_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &pp);
  // Verify that typeof(qq_inst) successfully resolved to module qq.
  EXPECT_EQ(
      qq_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &qq);
}

TEST(BuildSymbolTableTest, ModuleInstancesFromProjectMissingFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  VerilogProject project(sources_dir, {/* no include path */});

  SymbolTable symbol_table(&project);
  EXPECT_EQ(symbol_table.Project(), &project);

  std::vector<absl::Status> build_diagnostics;
  symbol_table.BuildSingleTranslationUnit("file/not/found.txt",
                                          &build_diagnostics);
  ASSERT_FALSE(build_diagnostics.empty());
  EXPECT_THAT(build_diagnostics.front().code(), absl::StatusCode::kNotFound);
}

TEST(BuildSymbolTableTest, ModuleInstancesFromProjectFilesGood) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include path */});

  // Linear dependency chain between 3 files.  Order arbitrarily chosen.
  constexpr absl::string_view  //
      text1(
          "module ss;\n"
          "  qq qq_inst();\n"  // instance
          "endmodule\n"),
      text2(
          "module pp;\n"
          "endmodule\n"),
      text3(
          "module qq;\n"
          "  pp pp_inst();\n"  // instance
          "endmodule\n");
  // Write to temporary files.
  const ScopedTestFile file1(sources_dir, text1);
  const ScopedTestFile file2(sources_dir, text2);
  const ScopedTestFile file3(sources_dir, text3);

  // Register files as part of project.
  for (const auto* file : {&file1, &file2, &file3}) {
    const auto status_or_file =
        project.OpenTranslationUnit(Basename(file->filename()));
    ASSERT_TRUE(status_or_file.ok());
  }

  SymbolTable symbol_table(&project);
  EXPECT_EQ(symbol_table.Project(), &project);

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  const SymbolTableNode& root_symbol(symbol_table.Root());

  // Goal: resolve the reference of "pp" to this definition node.
  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

  // Inspect inside the "qq" module definition.
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

  MUST_ASSIGN_LOOKUP_SYMBOL(ss, root_symbol, "ss");

  // "pp_inst" is an instance of type "pp"
  MUST_ASSIGN_LOOKUP_SYMBOL(pp_inst, qq, "pp_inst");

  // "qq_inst" is an instance of type "qq"
  MUST_ASSIGN_LOOKUP_SYMBOL(qq_inst, ss, "qq_inst");

  {
    ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
    const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
      const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "pp");
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "pp_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_inst_self_ref, ref_map, "pp_inst");
      EXPECT_TRUE(is_leaf(*pp_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(pp_inst_self_ref->components->Value().resolved_symbol,
                &pp_inst);
    }
  }
  {
    ASSERT_EQ(ss_info.local_references_to_bind.size(), 2);
    const auto ref_map(ss_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_type, ref_map, "qq");
      const ReferenceComponentNode* ref_node = qq_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "qq");
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "qq_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_inst_self_ref, ref_map, "qq_inst");
      EXPECT_TRUE(is_leaf(*qq_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(qq_inst_self_ref->components->Value().resolved_symbol,
                &qq_inst);
    }
  }

  {  // Verify pp_inst's type info
    EXPECT_TRUE(pp_inst_info.local_references_to_bind.empty());
    EXPECT_NE(pp_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& pp_type(
        pp_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(pp_type.identifier, "pp");
    EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
  }

  {  // Verify qq_inst's type info
    EXPECT_TRUE(qq_inst_info.local_references_to_bind.empty());
    EXPECT_NE(qq_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& qq_type(
        qq_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(qq_type.identifier, "qq");
    EXPECT_EQ(qq_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(qq_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(qq_type.required_metatype, SymbolMetaType::kUnspecified);
  }

  // Resolve symbols.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);

  // Verify that typeof(pp_inst) successfully resolved to module pp.
  EXPECT_EQ(
      pp_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &pp);
  // Verify that typeof(qq_inst) successfully resolved to module qq.
  EXPECT_EQ(
      qq_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &qq);
}

TEST(BuildSymbolTableTest, SingleFileModuleInstanceCyclicDependencies) {
  // Cyclic dependencies among three modules in one file.
  // Make sure this can still build and resolve without hanging,
  // even if this is semantically illegal.
  TestVerilogSourceFile src("cycle.sv",
                            "module pp;\n"
                            "  ss ss_inst();\n"  // instance
                            "endmodule\n"
                            "module qq;\n"
                            "  pp pp_inst();\n"  // instance
                            "endmodule\n"
                            "module ss;\n"
                            "  qq qq_inst();\n"  // instance
                            "endmodule\n");
  {
    const auto status = src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }

  SymbolTable symbol_table(nullptr);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  const auto build_diagnostics = BuildSymbolTable(src, &symbol_table);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Goal: resolve the reference of "pp" to this definition node.
  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

  // Inspect inside the "qq" module definition.
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

  MUST_ASSIGN_LOOKUP_SYMBOL(ss, root_symbol, "ss");

  // "ss_inst" is an instance of type "ss"
  MUST_ASSIGN_LOOKUP_SYMBOL(ss_inst, pp, "ss_inst");

  // "pp_inst" is an instance of type "pp"
  MUST_ASSIGN_LOOKUP_SYMBOL(pp_inst, qq, "pp_inst");

  // "qq_inst" is an instance of type "qq"
  MUST_ASSIGN_LOOKUP_SYMBOL(qq_inst, ss, "qq_inst");

  EXPECT_EQ(pp_info.file_origin, &src);
  EXPECT_EQ(qq_info.file_origin, &src);
  EXPECT_EQ(ss_info.file_origin, &src);
  {
    ASSERT_EQ(pp_info.local_references_to_bind.size(), 2);
    const auto ref_map(pp_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ss_type, ref_map, "ss");
      const ReferenceComponentNode* ref_node = ss_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "ss");
      EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                      src.GetTextStructure()->Contents()));
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "ss_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ss_inst_self_ref, ref_map, "ss_inst");
      EXPECT_TRUE(is_leaf(*ss_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(ss_inst_self_ref->components->Value().resolved_symbol,
                &ss_inst);
    }
  }
  {
    ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
    const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
      const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "pp");
      EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                      src.GetTextStructure()->Contents()));
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "pp_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_inst_self_ref, ref_map, "pp_inst");
      EXPECT_TRUE(is_leaf(*pp_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(pp_inst_self_ref->components->Value().resolved_symbol,
                &pp_inst);
    }
  }
  {
    ASSERT_EQ(ss_info.local_references_to_bind.size(), 2);
    const auto ref_map(ss_info.LocalReferencesMapViewForTesting());
    {
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_type, ref_map, "qq");
      const ReferenceComponentNode* ref_node = qq_type->LastTypeComponent();
      ASSERT_NE(ref_node, nullptr);
      const ReferenceComponent& ref(ref_node->Value());
      EXPECT_EQ(ref.identifier, "qq");
      EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                      src.GetTextStructure()->Contents()));
      EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ref.resolved_symbol, nullptr);
    }
    {  // self-reference to "qq_inst" instance
      ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_inst_self_ref, ref_map, "qq_inst");
      EXPECT_TRUE(is_leaf(*qq_inst_self_ref->components));  // no named ports
      // self-reference is already bound.
      EXPECT_EQ(qq_inst_self_ref->components->Value().resolved_symbol,
                &qq_inst);
    }
  }

  {  // Verify ss_inst's type info
    EXPECT_TRUE(ss_inst_info.local_references_to_bind.empty());
    EXPECT_NE(ss_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& ss_type(
        ss_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(ss_type.identifier, "ss");
    EXPECT_EQ(ss_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(ss_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(ss_type.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(ss_inst_info.file_origin, &src);
  }

  {  // Verify pp_inst's type info
    EXPECT_TRUE(pp_inst_info.local_references_to_bind.empty());
    EXPECT_NE(pp_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& pp_type(
        pp_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(pp_type.identifier, "pp");
    EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(pp_inst_info.file_origin, &src);
  }

  {  // Verify qq_inst's type info
    EXPECT_TRUE(qq_inst_info.local_references_to_bind.empty());
    EXPECT_NE(qq_inst_info.declared_type.user_defined_type, nullptr);
    const ReferenceComponent& qq_type(
        qq_inst_info.declared_type.user_defined_type->Value());
    EXPECT_EQ(qq_type.identifier, "qq");
    EXPECT_EQ(qq_type.resolved_symbol, nullptr);  // nothing resolved yet
    EXPECT_EQ(qq_type.ref_type, ReferenceType::kUnqualified);
    EXPECT_EQ(qq_type.required_metatype, SymbolMetaType::kUnspecified);
    EXPECT_EQ(qq_inst_info.file_origin, &src);
  }

  // Resolve symbols.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);

  // Verify that typeof(ss_inst) successfully resolved to module ss.
  EXPECT_EQ(
      ss_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &ss);
  // Verify that typeof(pp_inst) successfully resolved to module pp.
  EXPECT_EQ(
      pp_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &pp);
  // Verify that typeof(qq_inst) successfully resolved to module qq.
  EXPECT_EQ(
      qq_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
      &qq);
}

TEST(BuildSymbolTableTest, MultiFileModuleInstanceCyclicDependencies) {
  // Cyclic dependencies among three files.
  // Make sure this can still build and resolve without hanging,
  // even if this is semantically illegal.
  TestVerilogSourceFile pp_src("pp.sv",
                               "module pp;\n"
                               "  ss ss_inst();\n"  // instance
                               "endmodule\n");
  TestVerilogSourceFile qq_src("qq.sv",
                               "module qq;\n"
                               "  pp pp_inst();\n"  // instance
                               "endmodule\n");
  TestVerilogSourceFile ss_src("ss.sv",
                               "module ss;\n"
                               "  qq qq_inst();\n"  // instance
                               "endmodule\n");
  {
    const auto status = pp_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }
  {
    const auto status = qq_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }
  {
    const auto status = ss_src.Parse();
    ASSERT_TRUE(status.ok()) << status.message();
  }

  // All permutations of the following file ordering should end up with the
  // same results.
  std::vector<const TestVerilogSourceFile*> ordering(
      {&pp_src, &qq_src, &ss_src});
  // start with the lexicographically "lowest" permutation
  SortSourceFiles(&ordering);
  int count = 0;
  do {
    SymbolTable symbol_table(nullptr);
    const SymbolTableNode& root_symbol(symbol_table.Root());

    for (const auto* src : ordering) {
      const auto build_diagnostics = BuildSymbolTable(*src, &symbol_table);
      EXPECT_EMPTY_STATUSES(build_diagnostics);
    }

    // Goal: resolve the reference of "pp" to this definition node.
    MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

    // Inspect inside the "qq" module definition.
    MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");

    MUST_ASSIGN_LOOKUP_SYMBOL(ss, root_symbol, "ss");

    // "ss_inst" is an instance of type "ss"
    MUST_ASSIGN_LOOKUP_SYMBOL(ss_inst, pp, "ss_inst");

    // "pp_inst" is an instance of type "pp"
    MUST_ASSIGN_LOOKUP_SYMBOL(pp_inst, qq, "pp_inst");

    // "qq_inst" is an instance of type "qq"
    MUST_ASSIGN_LOOKUP_SYMBOL(qq_inst, ss, "qq_inst");

    EXPECT_EQ(pp_info.file_origin, &pp_src);
    EXPECT_EQ(qq_info.file_origin, &qq_src);
    EXPECT_EQ(ss_info.file_origin, &ss_src);
    {
      ASSERT_EQ(pp_info.local_references_to_bind.size(), 2);
      const auto ref_map(pp_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ss_type, ref_map, "ss");
        const ReferenceComponentNode* ref_node = ss_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "ss");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        pp_src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "ss_inst" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(ss_inst_self_ref, ref_map, "ss_inst");
        EXPECT_TRUE(is_leaf(*ss_inst_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(ss_inst_self_ref->components->Value().resolved_symbol,
                  &ss_inst);
      }
    }
    {
      ASSERT_EQ(qq_info.local_references_to_bind.size(), 2);
      const auto ref_map(qq_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_type, ref_map, "pp");
        const ReferenceComponentNode* ref_node = pp_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "pp");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        qq_src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "pp_inst" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(pp_inst_self_ref, ref_map, "pp_inst");
        EXPECT_TRUE(is_leaf(*pp_inst_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(pp_inst_self_ref->components->Value().resolved_symbol,
                  &pp_inst);
      }
    }
    {
      ASSERT_EQ(ss_info.local_references_to_bind.size(), 2);
      const auto ref_map(ss_info.LocalReferencesMapViewForTesting());
      {
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_type, ref_map, "qq");
        const ReferenceComponentNode* ref_node = qq_type->LastTypeComponent();
        ASSERT_NE(ref_node, nullptr);
        const ReferenceComponent& ref(ref_node->Value());
        EXPECT_EQ(ref.identifier, "qq");
        EXPECT_TRUE(verible::IsSubRange(ref.identifier,
                                        ss_src.GetTextStructure()->Contents()));
        EXPECT_EQ(ref.ref_type, ReferenceType::kUnqualified);
        EXPECT_EQ(ref.required_metatype, SymbolMetaType::kUnspecified);
        EXPECT_EQ(ref.resolved_symbol, nullptr);
      }
      {  // self-reference to "qq_inst" instance
        ASSIGN_MUST_FIND_EXACTLY_ONE_REF(qq_inst_self_ref, ref_map, "qq_inst");
        EXPECT_TRUE(is_leaf(*qq_inst_self_ref->components));  // no named ports
        // self-reference is already bound.
        EXPECT_EQ(qq_inst_self_ref->components->Value().resolved_symbol,
                  &qq_inst);
      }
    }

    {  // Verify ss_inst's type info
      EXPECT_TRUE(ss_inst_info.local_references_to_bind.empty());
      EXPECT_NE(ss_inst_info.declared_type.user_defined_type, nullptr);
      const ReferenceComponent& ss_type(
          ss_inst_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(ss_type.identifier, "ss");
      EXPECT_EQ(ss_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(ss_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(ss_type.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(ss_inst_info.file_origin, &pp_src);
    }

    {  // Verify pp_inst's type info
      EXPECT_TRUE(pp_inst_info.local_references_to_bind.empty());
      EXPECT_NE(pp_inst_info.declared_type.user_defined_type, nullptr);
      const ReferenceComponent& pp_type(
          pp_inst_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(pp_type.identifier, "pp");
      EXPECT_EQ(pp_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(pp_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(pp_type.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(pp_inst_info.file_origin, &qq_src);
    }

    {  // Verify qq_inst's type info
      EXPECT_TRUE(qq_inst_info.local_references_to_bind.empty());
      EXPECT_NE(qq_inst_info.declared_type.user_defined_type, nullptr);
      const ReferenceComponent& qq_type(
          qq_inst_info.declared_type.user_defined_type->Value());
      EXPECT_EQ(qq_type.identifier, "qq");
      EXPECT_EQ(qq_type.resolved_symbol, nullptr);  // nothing resolved yet
      EXPECT_EQ(qq_type.ref_type, ReferenceType::kUnqualified);
      EXPECT_EQ(qq_type.required_metatype, SymbolMetaType::kUnspecified);
      EXPECT_EQ(qq_inst_info.file_origin, &ss_src);
    }

    // Resolve symbols.
    std::vector<absl::Status> resolve_diagnostics;
    symbol_table.Resolve(&resolve_diagnostics);
    EXPECT_EMPTY_STATUSES(resolve_diagnostics);

    // Verify that typeof(ss_inst) successfully resolved to module ss.
    EXPECT_EQ(
        ss_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
        &ss);
    // Verify that typeof(pp_inst) successfully resolved to module pp.
    EXPECT_EQ(
        pp_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
        &pp);
    // Verify that typeof(qq_inst) successfully resolved to module qq.
    EXPECT_EQ(
        qq_inst_info.declared_type.user_defined_type->Value().resolved_symbol,
        &qq);
    ++count;
  } while (PermuteSourceFiles(&ordering));
  EXPECT_EQ(count, 6);  // make sure we covered all permutations
}

TEST(BuildSymbolTableTest, IncludeModuleDefinition) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "module pp;\n"
                              "endmodule\n",
                              "module.sv");
  ScopedTestFile pp_src(sources_dir, "`include \"module.sv\"\n", "pp.sv");

  VerilogProject project(sources_dir, {sources_dir});
  const auto file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(file_or_status.ok()) << file_or_status.status().message();

  SymbolTable symbol_table(&project);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");

  const VerilogSourceFile* included = project.LookupRegisteredFile("module.sv");
  ASSERT_NE(included, nullptr);
  EXPECT_EQ(pp_info.file_origin, included);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludeWithoutProject) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "module pp;\n"
                              "endmodule\n",
                              "module.sv");
  TestVerilogSourceFile pp_src("pp.sv", "`include \"module.sv\"\n");

  SymbolTable symbol_table(nullptr);

  const auto build_diagnostics = BuildSymbolTable(pp_src, nullptr);
  // include files are ignored.
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludeFileNotFound) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile pp_src(sources_dir, "`include \"not-found.sv\"\n", "pp.sv");

  VerilogProject project(sources_dir, {sources_dir});
  const auto file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(file_or_status.ok()) << file_or_status.status().message();

  SymbolTable symbol_table(&project);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  ASSERT_FALSE(build_diagnostics.empty());
  EXPECT_EQ(build_diagnostics.front().code(), absl::StatusCode::kNotFound);

  EXPECT_TRUE(root_symbol.Children().empty());

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludeFileParseError) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "module 333;\n"  // syntax error
                              "endmodule\n",
                              "module.sv");
  ScopedTestFile pp_src(sources_dir, "`include \"module.sv\"\n", "pp.sv");

  VerilogProject project(sources_dir, {sources_dir});
  const auto file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(file_or_status.ok()) << file_or_status.status().message();

  SymbolTable symbol_table(&project);

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  ASSERT_FALSE(build_diagnostics.empty());
  EXPECT_EQ(build_diagnostics.front().code(),
            absl::StatusCode::kInvalidArgument);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludeFileEmpty) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "",  // empty
                              "empty.sv");
  ScopedTestFile pp_src(sources_dir, "`include \"empty.sv\"\n", "pp.sv");

  VerilogProject project(sources_dir, {sources_dir});
  const auto file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(file_or_status.ok()) << file_or_status.status().message();

  SymbolTable symbol_table(&project);

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludedTwiceFromOneFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "// verilog_syntax: parse-as-module-body\n"
                              "wire ww;\n",
                              "wires.sv");
  ScopedTestFile pp_src(sources_dir,
                        "module pp;\n"
                        "`include \"wires.sv\"\n"
                        "endmodule\n"
                        "module qq;\n"
                        "`include \"wires.sv\"\n"
                        "endmodule\n",
                        "pp.sv");

  VerilogProject project(sources_dir, {sources_dir});
  const auto file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(file_or_status.ok()) << file_or_status.status().message();
  const VerilogSourceFile* pp_file = *file_or_status;
  ASSERT_NE(pp_file, nullptr);

  SymbolTable symbol_table(&project);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");
  MUST_ASSIGN_LOOKUP_SYMBOL(pp_ww, pp, "ww");
  MUST_ASSIGN_LOOKUP_SYMBOL(qq_ww, qq, "ww");

  const VerilogSourceFile* included = project.LookupRegisteredFile("wires.sv");
  ASSERT_NE(included, nullptr);
  EXPECT_EQ(pp_info.file_origin, pp_file);
  EXPECT_EQ(qq_info.file_origin, pp_file);
  EXPECT_EQ(pp_ww_info.file_origin, included);
  EXPECT_EQ(qq_ww_info.file_origin, included);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

TEST(BuildSymbolTableTest, IncludedTwiceFromDifferentFiles) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // Create files.
  ScopedTestFile IncludedFile(sources_dir,
                              "// verilog_syntax: parse-as-module-body\n"
                              "wire ww;\n",
                              "wires.sv");
  ScopedTestFile pp_src(sources_dir,
                        "module pp;\n"
                        "`include \"wires.sv\"\n"
                        "endmodule\n",
                        "pp.sv");
  ScopedTestFile qq_src(sources_dir,
                        "module qq;\n"
                        "`include \"wires.sv\"\n"
                        "endmodule\n",
                        "qq.sv");

  VerilogProject project(sources_dir, {sources_dir});

  const auto pp_file_or_status =
      project.OpenTranslationUnit(Basename(pp_src.filename()));
  ASSERT_TRUE(pp_file_or_status.ok()) << pp_file_or_status.status().message();
  const VerilogSourceFile* pp_file = *pp_file_or_status;
  ASSERT_NE(pp_file, nullptr);

  const auto qq_file_or_status =
      project.OpenTranslationUnit(Basename(qq_src.filename()));
  ASSERT_TRUE(qq_file_or_status.ok()) << qq_file_or_status.status().message();
  const VerilogSourceFile* qq_file = *qq_file_or_status;
  ASSERT_NE(qq_file, nullptr);

  SymbolTable symbol_table(&project);
  const SymbolTableNode& root_symbol(symbol_table.Root());

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_EMPTY_STATUSES(build_diagnostics);

  MUST_ASSIGN_LOOKUP_SYMBOL(pp, root_symbol, "pp");
  MUST_ASSIGN_LOOKUP_SYMBOL(qq, root_symbol, "qq");
  MUST_ASSIGN_LOOKUP_SYMBOL(pp_ww, pp, "ww");
  MUST_ASSIGN_LOOKUP_SYMBOL(qq_ww, qq, "ww");

  const VerilogSourceFile* included = project.LookupRegisteredFile("wires.sv");
  ASSERT_NE(included, nullptr);
  EXPECT_EQ(pp_info.file_origin, pp_file);
  EXPECT_EQ(qq_info.file_origin, qq_file);
  EXPECT_EQ(pp_ww_info.file_origin, included);
  EXPECT_EQ(qq_ww_info.file_origin, included);

  // Resolve symbols.  Nothing to resolve.
  std::vector<absl::Status> resolve_diagnostics;
  symbol_table.Resolve(&resolve_diagnostics);
  EXPECT_EMPTY_STATUSES(resolve_diagnostics);
}

struct FileListTestCase {
  absl::string_view contents;
  std::vector<absl::string_view> expected_files;
};

TEST(ParseSourceFileListFromFileTest, FileNotFound) {
  FileList file_list;
  const auto status(AppendFileListFromFile("/no/such/file.txt", &file_list));
  EXPECT_FALSE(status.ok());
}

TEST(ParseSourceFileListFromFileTest, VariousValidFiles) {
  const FileListTestCase kTestCases[] = {
      {"", {}},                // empty
      {"\n\n", {}},            // blank lines
      {"foo.sv", {"foo.sv"}},  // missing terminating newline, but still works
      {"foo.sv\n", {"foo.sv"}},
      {"file name contains space.sv\n", {"file name contains space.sv"}},
      {"foo/bar.sv\n", {"foo/bar.sv"}},  // with path separator
      {" foo.sv\n", {"foo.sv"}},         // remove leading whitespace
      {"foo.sv \n", {"foo.sv"}},         // remove trailing whitespace
      {"#foo.sv\n", {}},                 // commented out
      {"# foo.sv\n", {}},                // commented out
      {"foo.sv\nbar/bar.sv\n", {"foo.sv", "bar/bar.sv"}},
      {"/foo/bar.sv\n"
       "### ignore this one\n"
       "bar/baz.txt\n",
       {"/foo/bar.sv", "bar/baz.txt"}},
  };
  for (const auto& test : kTestCases) {
    const ScopedTestFile test_file(testing::TempDir(), test.contents);
    FileList file_list;
    const auto status(AppendFileListFromFile(test_file.filename(), &file_list));
    ASSERT_TRUE(status.ok()) << status;
    EXPECT_THAT(file_list.file_paths, ElementsAreArray(test.expected_files))
        << "input: " << test.contents;
  }
}

}  // namespace
}  // namespace verilog
