load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
load("@protobuf//bazel:proto_library.bzl", "proto_library")
load("@protobuf//rust:defs.bzl", "rust_proto_library")
load(
    "@rules_rust//rust:defs.bzl",
    "rust_library",
    "rust_test",
)
load(
    "//common:multiplatform_testing.bzl",
    "multiplatform_rust_test",
)

_PROFILING_RUSTC_FLAGS = select({
    "//rs_bindings_from_cc:enable_heap_profiling": ["--cfg=enable_heap_profiling"],
    "//conditions:default": [],
})

proto_library(
    name = "generate_bindings_proto",
    srcs = ["generate_bindings.proto"],
    visibility = ["//:__subpackages__"],
    deps = ["//rs_bindings_from_cc:ir_proto"],
)

cc_proto_library(
    name = "generate_bindings_cc_proto",
    visibility = ["//:__subpackages__"],
    deps = [":generate_bindings_proto"],
)

rust_proto_library(
    name = "generate_bindings_rust_proto",
    visibility = ["//:__subpackages__"],
    deps = [":generate_bindings_proto"],
)

rust_library(
    name = "cc_api_ffi",
    srcs = [
        "cc_api_ffi.rs",
        "cc_api_ffi_serialized_proto.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cc_api",
        ":generate_bindings_rust_proto",
        "//common:ffi_types",
        "@protobuf//rust:protobuf",
    ],
)

rust_library(
    name = "cc_api",
    srcs = [
        "cc_api.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":generate_bindings",
        ":generate_bindings_rust_proto",
        "//common:arc_anyhow",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_rust_proto",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@protobuf//rust:protobuf",
    ],
)

rust_library(
    name = "generate_bindings",
    srcs = [
        "generate_dyn_callable.rs",
        "lib.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cpp_type_name",
        ":generate_comment",
        ":generate_enum",
        ":generate_function",
        ":generate_function_thunk",
        ":generate_struct_and_union",
        ":has_bindings",
        ":lifetime_defaults_transform",
        ":rs_type_kind",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_abi_type",
        "//common:crubit_feature",
        "//common:dyn_format",
        "//common:error_report",
        "//common:errors",
        "//common:kythe_metadata",
        "//common:token_stream_printer",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:flagset",  # v0_4
        "@crate_index//:heck",  # v0_5
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:syn",  # v1
        "@crate_index//:unicode-ident",
    ],
)

multiplatform_rust_test(
    name = "generate_bindings_test",
    srcs = ["generate_bindings_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":multiplatform_ir_testing",
        ":test_generators",
        "//common:arc_anyhow",
        "//common:crubit_feature",
        "//common:multiplatform_testing",
        "//common:token_stream_matchers",
        "//common:token_stream_printer",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:googletest",
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:static_assertions",  # v1
        "@crate_index//:syn",  # v1
    ],
)

rust_library(
    name = "cpp_type_name",
    srcs = ["cpp_type_name.rs"],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
    ],
)

rust_library(
    name = "generate_struct_and_union",
    srcs = [
        "generate_struct_and_union.rs",
    ],
    edition = "2024",
    rustc_flags = _PROFILING_RUSTC_FLAGS,
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cpp_type_name",
        ":generate_comment",
        ":lifetime_defaults_transform",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:flagset",  # v0_4
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
    ],
)

multiplatform_rust_test(
    name = "generate_struct_and_union_test",
    srcs = ["generate_struct_and_union_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":generate_bindings",
        ":generate_struct_and_union",
        ":multiplatform_ir_testing",
        ":test_generators",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_feature",
        "//common:multiplatform_testing",
        "//common:token_stream_matchers",
        "//common:token_stream_printer",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:googletest",
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:static_assertions",  # v1
        "@crate_index//:syn",  # v1
    ],
)

rust_library(
    name = "multiplatform_ir_testing",
    testonly = True,
    srcs = ["multiplatform_ir_testing.rs"],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        "//common:arc_anyhow",
        "//common:multiplatform_testing",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_rust_proto",
        "//rs_bindings_from_cc:ir_testing",
    ],
)

rust_library(
    name = "test_generators",
    testonly = True,
    srcs = ["test_generators.rs"],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":generate_bindings",
        ":multiplatform_ir_testing",
        "//common:arc_anyhow",
        "//common:dyn_format",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
    ],
)

rust_library(
    name = "generate_comment",
    srcs = [
        "generate_comment.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        "//common:code_gen_utils",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:once_cell",  # v1
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:regex",  # v1
    ],
)

rust_test(
    name = "generate_comment_test",
    srcs = ["generate_comment_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":generate_bindings",
        ":generate_comment",
        "//common:arc_anyhow",
        "//common:error_report",
        "//common:token_stream_matchers",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:googletest",
        "@crate_index//:quote",  # v1
    ],
)

rust_library(
    name = "generate_enum",
    srcs = [
        "generate_enum.rs",
    ],
    edition = "2024",
    rustc_flags = _PROFILING_RUSTC_FLAGS,
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":generate_comment",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:flagset",  # v0_4
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
    ],
)

multiplatform_rust_test(
    name = "generate_enum_test",
    srcs = ["generate_enum_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":generate_bindings",
        ":multiplatform_ir_testing",
        ":test_generators",
        "//common:arc_anyhow",
        "//common:crubit_feature",
        "//common:multiplatform_testing",
        "//common:token_stream_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "@crate_index//:googletest",
        "@crate_index//:quote",  # v1
    ],
)

rust_library(
    name = "generate_function_thunk",
    srcs = [
        "generate_function_thunk.rs",
    ],
    edition = "2024",
    rustc_flags = _PROFILING_RUSTC_FLAGS,
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cpp_type_name",
        ":lifetime_defaults_transform",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_abi_type",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:rustc-stable-hash",
        "@crate_index//:syn",  # v1
        "@crate_index//:unicode-ident",
    ],
)

rust_library(
    name = "generate_function",
    srcs = [
        "generate_function.rs",
    ],
    edition = "2024",
    rustc_flags = _PROFILING_RUSTC_FLAGS,
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cpp_type_name",
        ":generate_comment",
        ":generate_function_thunk",
        ":has_bindings",
        ":lifetime_defaults_transform",
        "//cc_bindings_from_rs:rustversion",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_abi_type",
        "//common:crubit_feature",
        "//common:error_report",
        "//common:errors",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:flagset",  # v0_4
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:syn",  # v1
    ],
)

multiplatform_rust_test(
    name = "generate_function_test",
    srcs = ["generate_function_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":generate_bindings",
        ":generate_function_thunk",
        ":multiplatform_ir_testing",
        ":test_generators",
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_feature",
        "//common:error_report",
        "//common:multiplatform_testing",
        "//common:token_stream_matchers",
        "//common:token_stream_printer",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:googletest",
        "@crate_index//:quote",  # v1
        "@crate_index//:static_assertions",  # v1
        "@crate_index//:syn",  # v1
    ],
)

rust_library(
    name = "has_bindings",
    srcs = [
        "has_bindings.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":generate_function_thunk",
        "//common:arc_anyhow",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:heck",  # v0_5
    ],
)

rust_library(
    name = "lifetime_defaults_transform",
    srcs = [
        "lifetime_defaults_transform.rs",
    ],
    edition = "2024",
    rustc_flags = _PROFILING_RUSTC_FLAGS,
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        "//common:arc_anyhow",
        "//common:code_gen_utils",
        "//common:crubit_abi_type",
        "//common:crubit_feature",
        "//common:error_report",
        "//common:memoized",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
        "@crate_index//:syn",  # v1
        "@crate_index//:unicode-ident",
    ],
)

multiplatform_rust_test(
    name = "lifetime_defaults_transform_test",
    timeout = "long",
    srcs = ["lifetime_defaults_transform_test.rs"],
    tags = [
        "not_run:arm",
        "not_run:mac",
    ],
    visibility = ["//cargo:__subpackages__"],
    deps = [
        ":generate_bindings",
        ":lifetime_defaults_transform",
        ":multiplatform_ir_testing",
        ":test_generators",
        "//common:arc_anyhow",
        "//common:error_report",
        "//common:multiplatform_testing",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc:ir_matchers",
        "//rs_bindings_from_cc:ir_testing",
        "//rs_bindings_from_cc/generate_bindings/database",
        "@crate_index//:googletest",
        "@crate_index//:itertools",  # v0_13
        "@crate_index//:proc-macro2",
        "@crate_index//:quote",  # v1
    ],
)

rust_library(
    name = "rs_type_kind",
    srcs = [
        "rs_type_kind.rs",
    ],
    edition = "2024",
    visibility = [
        "//cargo:__subpackages__",
        "//rs_bindings_from_cc:__subpackages__",
    ],
    deps = [
        ":cpp_type_name",
        ":has_bindings",
        ":lifetime_defaults_transform",
        "//common:arc_anyhow",
        "//common:crubit_feature",
        "//common:error_report",
        "//rs_bindings_from_cc:ir",
        "//rs_bindings_from_cc/generate_bindings/database",
    ],
)
