Create proto_toolchain rule and macro

The proto_toolchain rule serves to define what protoc is used and to generate descriptor sets by proto_library.

This is a stripped down version of proto_lang_toolchain. It's not possible to set plugins or runtime libraries on it.

Steps in migration:
- this and other changes to proto_lang_toolchain
- release rules_proto, rules_java, rules_cc, rules_python
- use new version and define toolchains in protobuf repo

Issue: https://github.com/bazelbuild/rules_proto/issues/179
PiperOrigin-RevId: 566390506
diff --git a/proto/BUILD b/proto/BUILD
index 26e66f6..907b091 100644
--- a/proto/BUILD
+++ b/proto/BUILD
@@ -13,6 +13,17 @@
 )
 
 bzl_library(
+    name = "proto_toolchain_bzl",
+    srcs = [
+        "proto_toolchain.bzl",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//proto/private/rules:proto_toolchain_bzl",
+    ],
+)
+
+bzl_library(
     name = "repositories",
     srcs = [
         "repositories.bzl",
diff --git a/proto/private/rules/BUILD b/proto/private/rules/BUILD
index a2fd159..0d78785 100644
--- a/proto/private/rules/BUILD
+++ b/proto/private/rules/BUILD
@@ -12,3 +12,14 @@
         "//proto/private:native",
     ],
 )
+
+bzl_library(
+    name = "proto_toolchain_bzl",
+    srcs = [
+        "proto_toolchain.bzl",
+        "proto_toolchain_rule.bzl",
+    ],
+    visibility = [
+        "//proto:__subpackages__",
+    ],
+)
diff --git a/proto/private/rules/proto_toolchain.bzl b/proto/private/rules/proto_toolchain.bzl
new file mode 100644
index 0000000..a091b80
--- /dev/null
+++ b/proto/private/rules/proto_toolchain.bzl
@@ -0,0 +1,40 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Macro wrapping the proto_toolchain implementation.
+
+The macro additionally creates toolchain target when toolchain_type is given.
+"""
+
+load(":proto_toolchain_rule.bzl", _proto_toolchain_rule = "proto_toolchain")
+
+def proto_toolchain(*, name, proto_compiler, exec_compatible_with = []):
+    """Creates a proto_toolchain and toolchain target for proto_library.
+
+    Toolchain target is suffixed with "_toolchain".
+
+    Args:
+      name: name of the toolchain
+      proto_compiler: (Label) of either proto compiler sources or prebuild binaries
+      exec_compatible_with: ([constraints]) List of constraints the prebuild binary is compatible with.
+    """
+    _proto_toolchain_rule(name = name, proto_compiler = proto_compiler)
+
+    native.toolchain(
+        name = name + "_toolchain",
+        toolchain_type = "//proto:toolchain_type",
+        exec_compatible_with = exec_compatible_with,
+        target_compatible_with = [],
+        toolchain = name,
+    )
diff --git a/proto/private/rules/proto_toolchain_rule.bzl b/proto/private/rules/proto_toolchain_rule.bzl
new file mode 100644
index 0000000..836bb53
--- /dev/null
+++ b/proto/private/rules/proto_toolchain_rule.bzl
@@ -0,0 +1,56 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""A Starlark implementation of the proto_toolchain rule."""
+
+load("//proto:proto_common.bzl", "ProtoLangToolchainInfo")
+
+def _impl(ctx):
+    return [
+        DefaultInfo(
+            files = depset(),
+            runfiles = ctx.runfiles(),
+        ),
+        platform_common.ToolchainInfo(
+            proto = ProtoLangToolchainInfo(
+                out_replacement_format_flag = ctx.attr.command_line,
+                output_files = ctx.attr.output_files,
+                plugin = None,
+                runtime = None,
+                proto_compiler = ctx.attr.proto_compiler.files_to_run,
+                protoc_opts = ctx.fragments.proto.experimental_protoc_opts,
+                progress_message = ctx.attr.progress_message,
+                mnemonic = ctx.attr.mnemonic,
+                allowlist_different_package = None,
+            ),
+        ),
+    ]
+
+proto_toolchain = rule(
+    _impl,
+    attrs =
+        {
+            "progress_message": attr.string(default = "Generating Descriptor Set proto_library %{label}"),
+            "mnemonic": attr.string(default = "GenProtoDescriptorSet"),
+            "command_line": attr.string(default = "--descriptor_set_out=%s"),
+            "output_files": attr.string(values = ["single", "multiple", "legacy"], default = "single"),
+            "proto_compiler": attr.label(
+                cfg = "exec",
+                executable = True,
+                allow_files = True,  # Used by mocks in tests. Consider fixing tests and removing it.
+            ),
+        },
+    provides = [platform_common.ToolchainInfo],
+    fragments = ["proto"],
+)
diff --git a/proto/proto_common.bzl b/proto/proto_common.bzl
new file mode 100644
index 0000000..6184971
--- /dev/null
+++ b/proto/proto_common.bzl
@@ -0,0 +1,24 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+# Utilities for protocol buffers.
+#
+# https://docs.bazel.build/versions/master/skylark/lib/proto_common.html
+"""proto_common module"""
+
+load("//proto/private:native.bzl", "native_proto_common")
+
+proto_common = native_proto_common
+
+ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
diff --git a/proto/proto_toolchain.bzl b/proto/proto_toolchain.bzl
new file mode 100644
index 0000000..e1a853c
--- /dev/null
+++ b/proto/proto_toolchain.bzl
@@ -0,0 +1,19 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Export for proto_toolchain"""
+
+load("//proto/private/rules:proto_toolchain.bzl", _proto_toolchain_macro = "proto_toolchain")
+
+proto_toolchain = _proto_toolchain_macro