load("//tools/lint:lint.bzl", "add_lint_tests")
load(
    "//tools/skylark:alias.bzl",
    "drake_cc_hdrs_forwarding_library",
)
load(
    "//tools/skylark:drake_cc.bzl",
    "drake_cc_googletest",
    "drake_cc_library",
    "drake_cc_package_library",
)

package(default_visibility = ["//visibility:public"])

drake_cc_package_library(
    name = "framework",
    visibility = ["//visibility:public"],
    deps = [
        ":abstract_value_cloner",
        ":abstract_values",
        ":cache_and_dependency_tracker",
        ":cache_entry",
        ":context",
        ":context_base",
        ":continuous_state",
        ":diagram",
        ":diagram_builder",
        ":diagram_context",
        ":diagram_continuous_state",
        ":diagram_discrete_values",
        ":diagram_output_port",
        ":diagram_state",
        ":discrete_values",
        ":event_collection",
        ":framework_common",
        ":input_port",
        ":input_port_base",
        ":leaf_context",
        ":leaf_output_port",
        ":leaf_system",
        ":model_values",
        ":output_port",
        ":output_port_base",
        ":parameters",
        ":port_base",
        ":single_output_vector_source",
        ":state",
        ":system",
        ":system_base",
        ":system_constraint",
        ":system_output",
        ":system_scalar_converter",
        ":system_symbolic_inspector",
        ":system_visitor",
        ":value_checker",
        ":value_producer",
        ":value_to_abstract_value",
        ":vector",
        ":vector_system",
        ":witness_function",
    ],
)

drake_cc_library(
    name = "vector",
    srcs = [
        "basic_vector.cc",
        "subvector.cc",
        "supervector.cc",
        "vector_base.cc",
    ],
    hdrs = [
        "basic_vector.h",
        "subvector.h",
        "supervector.h",
        "vector_base.h",
    ],
    deps = [
        "//common:default_scalars",
        "//common:dummy_value",
        "//common:essential",
        "//common:nice_type_name",
        "//common:unused",
    ],
)

drake_cc_library(
    name = "value_to_abstract_value",
    hdrs = [
        "value_to_abstract_value.h",
    ],
    deps = [
        ":vector",
        "//common:essential",
        "//common:value",
        "@fmt",
    ],
)

drake_cc_library(
    name = "value_checker",
    srcs = [],
    hdrs = ["value_checker.h"],
    visibility = [":__subpackages__"],
    deps = [
        ":vector",
        "//common:essential",
        "//common:nice_type_name",
        "//common:value",
    ],
)

drake_cc_library(
    name = "abstract_value_cloner",
    srcs = ["abstract_value_cloner.cc"],
    hdrs = ["abstract_value_cloner.h"],
    deps = [
        "//common:copyable_unique_ptr",
        "//common:value",
    ],
)

drake_cc_library(
    name = "abstract_values",
    srcs = ["abstract_values.cc"],
    hdrs = ["abstract_values.h"],
    deps = [
        ":framework_common",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "continuous_state",
    srcs = ["continuous_state.cc"],
    hdrs = ["continuous_state.h"],
    deps = [
        ":framework_common",
        ":system_scalar_converter",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "discrete_values",
    srcs = ["discrete_values.cc"],
    hdrs = ["discrete_values.h"],
    deps = [
        ":framework_common",
        ":system_scalar_converter",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "state",
    srcs = ["state.cc"],
    hdrs = ["state.h"],
    deps = [
        ":abstract_values",
        ":continuous_state",
        ":discrete_values",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "event_collection",
    srcs = [
        "event_collection.cc",
        "event_status.cc",
    ],
    hdrs = [
        "event.h",
        "event_collection.h",
        "event_status.h",
    ],
    deps = [
        ":abstract_values",
        ":context",
        ":system_base",
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "parameters",
    srcs = ["parameters.cc"],
    hdrs = ["parameters.h"],
    deps = [
        ":abstract_values",
        ":discrete_values",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "framework_common",
    srcs = [],
    hdrs = [
        "framework_common.h",
    ],
    deps = [
        "//common:identifier",
        "//common:type_safe_index",
        "//common:value",
    ],
)

# Cache and dependencies are coupled because dependency trackers need inline
# access to cache entries in order to invalidate them very, very fast.
drake_cc_library(
    name = "cache_and_dependency_tracker",
    srcs = [
        "cache.cc",
        "dependency_tracker.cc",
    ],
    hdrs = [
        "cache.h",
        "dependency_tracker.h",
    ],
    deps = [
        ":framework_common",
        "//common:copyable_unique_ptr",
        "//common:reset_on_copy",
        "//common:unused",
        "//common:value",
    ],
)

drake_cc_library(
    name = "context_base",
    srcs = [
        "context_base.cc",
        "fixed_input_port_value.cc",
    ],
    hdrs = [
        "context_base.h",
        "fixed_input_port_value.h",
    ],
    deps = [
        ":cache_and_dependency_tracker",
        ":framework_common",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "cache_entry",
    srcs = [
        "cache_entry.cc",
    ],
    hdrs = [
        "cache_entry.h",
    ],
    deps = [
        ":context_base",
        ":value_producer",
    ],
)

drake_cc_library(
    name = "port_base",
    srcs = [
        "port_base.cc",
    ],
    hdrs = [
        "port_base.h",
    ],
    deps = [
        ":framework_common",
        ":vector",
        "//common:nice_type_name",
    ],
)

drake_cc_library(
    name = "input_port_base",
    srcs = [
        "input_port_base.cc",
    ],
    hdrs = [
        "input_port_base.h",
    ],
    deps = [
        ":context_base",
        ":framework_common",
        ":port_base",
        ":value_producer",
        "//common:nice_type_name",
        "//common:random",
    ],
)

drake_cc_library(
    name = "output_port_base",
    srcs = [
        "output_port_base.cc",
    ],
    hdrs = [
        "output_port_base.h",
    ],
    deps = [
        ":framework_common",
        ":port_base",
        "//common:nice_type_name",
    ],
)

drake_cc_library(
    name = "system_base",
    srcs = [
        "system_base.cc",
    ],
    hdrs = [
        "system_base.h",
    ],
    deps = [
        ":abstract_value_cloner",
        ":cache_entry",
        ":context_base",
        ":input_port_base",
        ":output_port_base",
        ":value_producer",
    ],
)

drake_cc_library(
    name = "system_output",
    srcs = ["system_output.cc"],
    hdrs = [
        "system_output.h",
    ],
    deps = [
        ":framework_common",
        ":value_checker",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
        "//common:pointer_cast",
        "//common:value",
    ],
)

drake_cc_library(
    name = "context",
    srcs = ["context.cc"],
    hdrs = ["context.h"],
    deps = [
        ":context_base",
        ":parameters",
        ":state",
        "//common:default_scalars",
        "//common:essential",
        "//common:pointer_cast",
    ],
)

drake_cc_library(
    name = "leaf_context",
    srcs = ["leaf_context.cc"],
    hdrs = ["leaf_context.h"],
    deps = [
        ":cache_and_dependency_tracker",
        ":context",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "input_port",
    srcs = [
        "input_port.cc",
    ],
    hdrs = [
        "input_port.h",
    ],
    deps = [
        ":context",
        ":input_port_base",
        ":value_to_abstract_value",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "output_port",
    srcs = [
        "output_port.cc",
    ],
    hdrs = [
        "output_port.h",
    ],
    deps = [
        ":context",
        ":output_port_base",
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "witness_function",
    srcs = ["witness_function.cc"],
    hdrs = ["witness_function.h"],
    deps = [
        ":context",
        ":event_collection",
        ":system_base",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "value_producer",
    srcs = ["value_producer.cc"],
    hdrs = ["value_producer.h"],
    deps = [
        ":abstract_value_cloner",
        ":context_base",
        ":framework_common",
        "//common:copyable_unique_ptr",
        "//common:nice_type_name",
        "//common:value",
    ],
)

drake_cc_library(
    name = "system",
    srcs = ["system.cc"],
    hdrs = ["system.h"],
    deps = [
        ":context",
        ":event_collection",
        ":input_port",
        ":output_port",
        ":system_base",
        ":system_constraint",
        ":system_output",
        ":system_scalar_converter",
        ":system_visitor",
        ":witness_function",
        "//common:default_scalars",
        "//common:essential",
        "//common:pointer_cast",
        "//common:random",
        "//common:type_safe_index",
        "//common:unused",
        "//common:value",
    ],
)

drake_cc_library(
    name = "leaf_output_port",
    srcs = ["leaf_output_port.cc"],
    hdrs = ["leaf_output_port.h"],
    deps = [
        ":cache_entry",
        ":framework_common",
        ":output_port",
        ":value_producer",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
        "//common:nice_type_name",
        "//common:value",
    ],
)

drake_cc_library(
    name = "model_values",
    srcs = ["model_values.cc"],
    hdrs = ["model_values.h"],
    visibility = [":__subpackages__"],
    deps = [
        ":vector",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "system_scalar_converter",
    srcs = [
        "scalar_conversion_traits.cc",
        "system_scalar_converter.cc",
        "system_type_tag.cc",
    ],
    hdrs = [
        "scalar_conversion_traits.h",
        "system_scalar_converter.h",
        "system_type_tag.h",
    ],
    deps = [
        "//common:default_scalars",
        "//common:essential",
        "//common:hash",
        "//common:nice_type_name",
    ],
)

drake_cc_library(
    name = "leaf_system",
    srcs = ["leaf_system.cc"],
    hdrs = ["leaf_system.h"],
    interface_deps = [
        ":abstract_value_cloner",
        ":leaf_context",
        ":leaf_output_port",
        ":model_values",
        ":system",
        ":system_scalar_converter",
        ":value_producer",
        "//common:default_scalars",
        "//common:essential",
        "//common:unused",
    ],
    deps = [
        ":system_symbolic_inspector",
        ":value_checker",
        "//common:pointer_cast",
        "@abseil_cpp_internal//absl/container:inlined_vector",
    ],
)

drake_cc_library(
    name = "diagram_continuous_state",
    srcs = ["diagram_continuous_state.cc"],
    hdrs = ["diagram_continuous_state.h"],
    deps = [
        ":continuous_state",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
        "//common:pointer_cast",
    ],
)

drake_cc_library(
    name = "diagram_discrete_values",
    srcs = ["diagram_discrete_values.cc"],
    hdrs = ["diagram_discrete_values.h"],
    deps = [
        ":discrete_values",
        "//common:default_scalars",
        "//common:essential",
        "//common:pointer_cast",
    ],
)

drake_cc_library(
    name = "diagram_state",
    srcs = ["diagram_state.cc"],
    hdrs = ["diagram_state.h"],
    deps = [
        ":diagram_continuous_state",
        ":diagram_discrete_values",
        ":state",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "diagram_context",
    srcs = ["diagram_context.cc"],
    hdrs = ["diagram_context.h"],
    deps = [
        ":context",
        ":diagram_state",
        ":vector",
        "//common:default_scalars",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "diagram_output_port",
    srcs = ["diagram_output_port.cc"],
    hdrs = ["diagram_output_port.h"],
    deps = [
        ":diagram_context",
        ":framework_common",
        ":output_port",
        "//common:default_scalars",
        "//common:essential",
        "//common:value",
    ],
)

drake_cc_library(
    name = "diagram",
    srcs = ["diagram.cc"],
    hdrs = ["diagram.h"],
    interface_deps = [
        ":diagram_context",
        ":diagram_output_port",
        ":system",
        "//common:default_scalars",
        "//common:essential",
    ],
    deps = [
        ":abstract_value_cloner",
        "//common:pointer_cast",
        "//common:string_container",
    ],
)

drake_cc_library(
    name = "diagram_builder",
    srcs = ["diagram_builder.cc"],
    hdrs = ["diagram_builder.h"],
    interface_deps = [
        ":diagram",
        "//common:default_scalars",
        "//common:essential",
        "//common:string_container",
    ],
    deps = [
        "//common:pointer_cast",
    ],
)

drake_cc_library(
    name = "system_constraint",
    srcs = ["system_constraint.cc"],
    hdrs = ["system_constraint.h"],
    deps = [
        ":context",
        "//common:default_scalars",
        "//common:essential",
        "//common:type_safe_index",
        "//common:unused",
    ],
)

drake_cc_library(
    name = "system_visitor",
    srcs = ["system_visitor.cc"],
    hdrs = ["system_visitor.h"],
    deps = [
        "//common:default_scalars",
    ],
)

drake_cc_library(
    name = "system_symbolic_inspector",
    srcs = ["system_symbolic_inspector.cc"],
    hdrs = ["system_symbolic_inspector.h"],
    interface_deps = [
        "//common/symbolic:expression",
        ":system",
    ],
    deps = [
        "//common/symbolic:polynomial",
    ],
)

drake_cc_library(
    name = "single_output_vector_source",
    srcs = ["single_output_vector_source.cc"],
    hdrs = ["single_output_vector_source.h"],
    deps = [
        ":leaf_system",
        "//common:default_scalars",
    ],
)

drake_cc_library(
    name = "vector_system",
    srcs = ["vector_system.cc"],
    hdrs = ["vector_system.h"],
    deps = [
        ":leaf_system",
        "//common:default_scalars",
        "//common:unused",
    ],
)

# === test/ ===

drake_cc_googletest(
    name = "abstract_value_cloner_test",
    deps = [
        ":abstract_value_cloner",
        ":vector",
    ],
)

drake_cc_googletest(
    name = "basic_vector_test",
    deps = [
        ":vector",
        "//common:essential",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "cache_test",
    deps = [
        ":cache_and_dependency_tracker",
        ":context_base",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "cache_entry_test",
    deps = [
        ":cache_entry",
        ":system_base",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "continuous_state_test",
    deps = [
        ":continuous_state",
        ":diagram_continuous_state",
        "//common:essential",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "diagram_builder_test",
    deps = [
        ":diagram_builder",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//common/trajectories",
        "//systems/primitives:adder",
        "//systems/primitives:constant_vector_source",
        "//systems/primitives:demultiplexer",
        "//systems/primitives:gain",
        "//systems/primitives:integrator",
        "//systems/primitives:pass_through",
    ],
)

drake_cc_googletest(
    name = "diagram_context_test",
    deps = [
        ":diagram_context",
        "//common:essential",
        "//common:pointer_cast",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:pack_value",
        "//systems/primitives:adder",
        "//systems/primitives:integrator",
    ],
)

drake_cc_googletest(
    name = "diagram_test",
    deps = [
        ":diagram",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//common/test_utilities:is_dynamic_castable",
        "//examples/pendulum:pendulum_plant",
        "//systems/analysis/test_utilities:stateless_system",
        "//systems/framework/test_utilities:initialization_test_system",
        "//systems/framework/test_utilities:pack_value",
        "//systems/framework/test_utilities:scalar_conversion",
        "//systems/primitives:adder",
        "//systems/primitives:constant_value_source",
        "//systems/primitives:constant_vector_source",
        "//systems/primitives:gain",
        "//systems/primitives:integrator",
        "//systems/primitives:zero_order_hold",
    ],
)

drake_cc_googletest(
    name = "discrete_values_test",
    deps = [
        ":diagram_discrete_values",
        ":discrete_values",
        "//common:essential",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//common/test_utilities:is_dynamic_castable",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "discrete_values_limit_malloc_test",
    deps = [
        ":discrete_values",
        "//common/test_utilities:limit_malloc",
    ],
)

drake_cc_googletest(
    name = "dependency_tracker_test",
    deps = [
        ":context_base",
        "//common",
        "//common/test_utilities:expect_no_throw",
    ],
)

drake_cc_googletest(
    name = "event_status_test",
    deps = [
        ":event_collection",
        ":leaf_system",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "event_test",
    deps = [
        ":event_collection",
    ],
)

drake_cc_googletest(
    name = "leaf_context_test",
    deps = [
        ":leaf_context",
        "//common:essential",
        "//common/test_utilities",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "leaf_system_test",
    deps = [
        ":leaf_system",
        "//common:essential",
        "//common/test_utilities",
        "//common/test_utilities:limit_malloc",
        "//systems/framework/test_utilities:initialization_test_system",
        "//systems/framework/test_utilities:my_vector",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "leaf_system_deprecation_test",
    deps = [
        ":leaf_system",
    ],
)

drake_cc_googletest(
    name = "model_values_test",
    deps = [
        ":model_values",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "abstract_values_test",
    deps = [
        ":abstract_values",
        "//common:essential",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "parameters_test",
    deps = [
        ":parameters",
        "//common:essential",
        "//systems/framework/test_utilities:pack_value",
    ],
)

drake_cc_googletest(
    name = "subvector_test",
    deps = [
        ":vector",
        "//common:essential",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "supervector_test",
    deps = [
        ":vector",
        "//common:essential",
    ],
)

drake_cc_googletest(
    name = "fixed_input_port_value_test",
    deps = [
        ":system_base",
        "//common:essential",
    ],
)

drake_cc_googletest(
    name = "system_output_test",
    deps = [
        ":system_output",
        "//common:essential",
        "//common/test_utilities:is_dynamic_castable",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "system_visitor_test",
    deps = [
        ":diagram_builder",
        ":system_visitor",
        "//systems/primitives:adder",
    ],
)

drake_cc_googletest(
    name = "input_port_test",
    deps = [
        ":diagram_builder",
        ":input_port",
        ":leaf_system",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "output_port_test",
    deps = [
        ":leaf_context",
        ":system",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
        "//systems/primitives:constant_vector_source",
    ],
)

drake_cc_googletest(
    name = "system_base_test",
    deps = [
        ":discrete_values",
        ":system_base",
        "//common:essential",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "system_test",
    deps = [
        ":abstract_value_cloner",
        ":leaf_context",
        ":leaf_output_port",
        ":system",
        "//common:essential",
        "//common:unused",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "value_checker_test",
    deps = [
        ":value_checker",
        "//common/test_utilities:expect_no_throw",
    ],
)

drake_cc_googletest(
    name = "value_to_abstract_value_test",
    deps = [
        ":value_to_abstract_value",
        "//common:essential",
        "//common:unused",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:my_vector",
    ],
)

drake_cc_googletest(
    name = "system_symbolic_inspector_test",
    deps = [
        ":leaf_system",
        ":system_symbolic_inspector",
        "//common/symbolic:polynomial",
        "//examples/pendulum:pendulum_plant",
    ],
)

drake_cc_googletest(
    name = "single_output_vector_source_test",
    deps = [
        ":single_output_vector_source",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "vector_system_test",
    deps = [
        ":vector_system",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework/test_utilities:scalar_conversion",
        "//systems/primitives:integrator",
    ],
)

drake_cc_googletest(
    name = "system_scalar_converter_test",
    deps = [
        ":leaf_system",
        ":system_scalar_converter",
        "//common/test_utilities",
        "//systems/framework/test_utilities:scalar_conversion",
    ],
)

drake_cc_googletest(
    name = "system_constraint_test",
    deps = [
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//systems/primitives:linear_system",
    ],
)

drake_cc_googletest(
    name = "system_scalar_conversion_doxygen_test",
    deps = [
        "//examples/pendulum:pendulum_plant",
    ],
)

drake_cc_googletest(
    name = "value_producer_test",
    deps = [
        ":abstract_value_cloner",
        ":leaf_context",
        ":value_producer",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "thread_sanitizer_test",
    deps = [
        ":vector_system",
        "//common/test_utilities",
    ],
)

add_lint_tests(enable_clang_format_lint = False)
