// Copyright 2020-2025 Buf Technologies, Inc.
//
// 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.

syntax = "proto3";

package buf.alpha.registry.v1alpha1;

import "buf/alpha/image/v1/image.proto";
import "google/protobuf/compiler/plugin.proto";
import "google/protobuf/timestamp.proto";

// CuratedPluginVisibility defines the visibility options available
// for Curated Plugins.
enum CuratedPluginVisibility {
  CURATED_PLUGIN_VISIBILITY_UNSPECIFIED = 0;
  CURATED_PLUGIN_VISIBILITY_PUBLIC = 1;
  CURATED_PLUGIN_VISIBILITY_PRIVATE = 2;
}

// The supported plugin registries for curated plugins.
enum PluginRegistryType {
  reserved 6;
  reserved "PLUGIN_REGISTRY_TYPE_ARCHIVE";

  PLUGIN_REGISTRY_TYPE_UNSPECIFIED = 0;
  PLUGIN_REGISTRY_TYPE_GO = 1;
  PLUGIN_REGISTRY_TYPE_NPM = 2;
  PLUGIN_REGISTRY_TYPE_MAVEN = 3;
  PLUGIN_REGISTRY_TYPE_SWIFT = 4;
  PLUGIN_REGISTRY_TYPE_PYTHON = 5;
  PLUGIN_REGISTRY_TYPE_CARGO = 7;
  PLUGIN_REGISTRY_TYPE_NUGET = 8;
  PLUGIN_REGISTRY_TYPE_CMAKE = 9;
}

// PluginLanguage is used to specify the output languages a plugin supports.
enum PluginLanguage {
  PLUGIN_LANGUAGE_UNSPECIFIED = 0;
  PLUGIN_LANGUAGE_GO = 1;
  PLUGIN_LANGUAGE_JAVASCRIPT = 2;
  PLUGIN_LANGUAGE_TYPESCRIPT = 3;
  PLUGIN_LANGUAGE_SWIFT = 4;
  PLUGIN_LANGUAGE_CPP = 5;
  PLUGIN_LANGUAGE_JAVA = 6;
  PLUGIN_LANGUAGE_DART = 7;
  PLUGIN_LANGUAGE_RUST = 8;
  PLUGIN_LANGUAGE_PYTHON = 9;
  PLUGIN_LANGUAGE_RUBY = 10;
  PLUGIN_LANGUAGE_KOTLIN = 11;
  PLUGIN_LANGUAGE_OBJECTIVE_C = 12;
  PLUGIN_LANGUAGE_PHP = 13;
  PLUGIN_LANGUAGE_CSHARP = 14;
  PLUGIN_LANGUAGE_SCALA = 15;
  PLUGIN_LANGUAGE_C = 16;
}

// NPMImportStyle is used to specify the import style the plugin supports.
enum NPMImportStyle {
  NPM_IMPORT_STYLE_UNSPECIFIED = 0;
  NPM_IMPORT_STYLE_MODULE = 1;
  NPM_IMPORT_STYLE_COMMONJS = 2;
}

// SwiftPlatformType is used to specify the platform type for a Swift plugins minimum compatible version.
enum SwiftPlatformType {
  SWIFT_PLATFORM_TYPE_UNSPECIFIED = 0;
  SWIFT_PLATFORM_TYPE_MACOS = 1;
  SWIFT_PLATFORM_TYPE_IOS = 2;
  SWIFT_PLATFORM_TYPE_WATCHOS = 3;
  SWIFT_PLATFORM_TYPE_TVOS = 4;
}

// PythonPackageType is used to specify the package type for a Python Generated SDK.
enum PythonPackageType {
  PYTHON_PACKAGE_TYPE_UNSPECIFIED = 0;
  // Regular Python package, containing Python runtime code (`.py` files).
  PYTHON_PACKAGE_TYPE_RUNTIME = 1;
  // Stub-only package, containing only `.pyi` files.
  // Ref: https://peps.python.org/pep-0561/#stub-only-packages
  PYTHON_PACKAGE_TYPE_STUB_ONLY = 2;
}

// DotnetTargetFramework specifies the target framework for dotnet plugins.
// This is not meant to be an exhaustive list - most plugins should target a
// netstandard version.
// Reference: https://learn.microsoft.com/en-us/dotnet/standard/frameworks
enum DotnetTargetFramework {
  DOTNET_TARGET_FRAMEWORK_UNSPECIFIED = 0;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_0 = 1;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_1 = 2;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_2 = 3;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_3 = 4;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_4 = 5;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_5 = 6;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_1_6 = 7;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_2_0 = 8;
  DOTNET_TARGET_FRAMEWORK_NETSTANDARD_2_1 = 9;
  DOTNET_TARGET_FRAMEWORK_NET_5_0 = 10;
  DOTNET_TARGET_FRAMEWORK_NET_6_0 = 11;
  DOTNET_TARGET_FRAMEWORK_NET_7_0 = 12;
  DOTNET_TARGET_FRAMEWORK_NET_8_0 = 13;
}

// GoConfig is the configuration for a Go plugin.
message GoConfig {
  // RuntimeLibrary describes the runtime library dependency of the generated code.
  message RuntimeLibrary {
    // The name of the runtime library module, i.e. "google.golang.org/protobuf".
    string module = 1;
    // The version of the runtime library, i.e. "v1.27.1".
    string version = 2;
  }
  // Optionally define the runtime libraries for the plugin.
  repeated RuntimeLibrary runtime_libraries = 1;
  // The minimum Go version required by the plugin.
  string minimum_version = 2;
  // Optionally specifies an alternate base plugin like "remote/org/go-multi" instead of the default
  // "remote/protocolbuffers/go". If provided, the name must match one of the plugin dependencies in
  // the top-level deps field.
  //
  // This affects how imports are resolved - the specified plugin's import path will be used as the
  // base path for all generated code, replacing the default protocolbuffers/go import paths. Used
  // when depending on non-default BSR plugins.
  string base_plugin = 3;
}

// NPMConfig is the configuration for a JavaScript NPM plugin.
message NPMConfig {
  // RuntimeLibrary describes the runtime library dependency of the generated code.
  message RuntimeLibrary {
    // The name of the runtime library package, i.e. "@grpc/grpc-js".
    string package = 1;
    // The version of the runtime library, i.e. "^1.27.1".
    string version = 2;
  }
  // Optionally define the runtime libraries for the plugin.
  repeated RuntimeLibrary runtime_libraries = 1;
  // Optionally define a configuration for rewriting import paths, a feature mainly
  // used for remote code generation in the BSR npm registry, which makes it possible
  // to serve the output of a BSR module and a plugin in an individual package.
  //
  // All plugins based on @bufbuild/protoplugin support the option "rewrite_imports".
  // Setting this value, i.e. "connectweb.js" or "pb.js", informs the BSR npm registry
  // that the plugin supports import rewrites with the given import suffix.
  string rewrite_import_path_suffix = 2;
  // The import style used for the "type" field in the package.json file.
  // This exists to support legacy plugins that require "commonjs" support.
  NPMImportStyle import_style = 3;
}

// MavenConfig is the configuration for a Maven plugin.
message MavenConfig {
  // RuntimeLibrary describes a runtime dependency of the generated code.
  message RuntimeLibrary {
    string group_id = 1;
    string artifact_id = 2;
    string version = 3;
    string classifier = 4;
    string extension = 5;
  }
  // CompilerConfig contains configuration for the Java and/or Kotlin compiler used when compiling the generated code.
  message CompilerConfig {
    CompilerJavaConfig java = 1;
    CompilerKotlinConfig kotlin = 2;
  }
  // CompilerJavaConfig contains settings for the Java compiler.
  message CompilerJavaConfig {
    // File encoding (default: UTF-8).
    string encoding = 1;
    // Release version (default: 8).
    int32 release = 2;
    // Source version (default: 8).
    int32 source = 3;
    // Target version (default: 8).
    int32 target = 4;
  }
  // CompilerKotlinConfig contains settings for the Kotlin compiler.
  message CompilerKotlinConfig {
    // Version of the Kotlin compiler used to compile the generated code.
    string version = 1;
    // Version of the Kotlin API to target.
    string api_version = 2;
    // Target version of the JVM bytecode (default: 1.8).
    string jvm_target = 3;
    // Kotlin language version used for source compatibility.
    string language_version = 4;
  }
  // RuntimeConfig allows configuring additional runtimes (like the 'lite' runtime).
  // They can use different runtime dependencies and plugin options.
  message RuntimeConfig {
    string name = 1;
    repeated RuntimeLibrary runtime_libraries = 2;
    // The options to pass to the plugin. These will
    // be merged into a single, comma-separated string.
    repeated string options = 3;
  }

  // Optionally define the runtime libraries for the plugin.
  repeated RuntimeLibrary runtime_libraries = 1;
  // Settings for the Java/Kotlin compiler used to compile the generated code.
  CompilerConfig compiler = 2;
  // Optional additional runtimes supported by the plugin.
  repeated RuntimeConfig additional_runtimes = 3;
}

// NugetConfig is the configuration for a NuGet C# plugin.
message NugetConfig {
  // RuntimeLibrary describes a NuGet package dependency of the generated code.
  // Ref: https://learn.microsoft.com/en-us/dotnet/core/tools/dependencies#the-packagereference-element
  message RuntimeLibrary {
    // The name of the NuGet package (also known as the package ID).
    string name = 1;
    // The version of the NuGet package (supports ranges).
    // Ref: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges
    string version = 2;
    // Optional target frameworks. If specified, these dependencies will be
    // conditionally added when building for the specified target framework.
    repeated DotnetTargetFramework target_frameworks = 3;
  }
  // Target frameworks to build. At least one target framework is required.
  repeated DotnetTargetFramework target_frameworks = 1;
  // Optional runtime libraries required by the plugin's generated code.
  repeated RuntimeLibrary runtime_libraries = 2;
}

// CmakeConfig is the configuration for a Cmake C++ plugin.
message CmakeConfig {}

message SwiftConfig {
  // RuntimeLibrary describes a runtime library dependency of the generated code.
  message RuntimeLibrary {
    // The source of the runtime library package, e.g. https://github.com/apple/swift-protobuf.git.
    string source = 1;
    // The name of the runtime library package, e.g. "swift-protobuf".
    string package = 2;
    // The version of the runtime library, e.g. "1.21.0".
    string version = 3;
    // The products exported by the runtime library, e.g. "SwiftProtobuf".
    repeated string products = 4;
    // The minimum compatible platform versions of the runtime library.
    message Platform {
      // The name of the platform.
      SwiftPlatformType name = 1;
      // The minimum compatible version of the platform.
      string version = 2;
    }
    // The minimum compatible platform versions of the runtime library.
    repeated Platform platforms = 5;
    // The supported Swift language versions of the runtime library, e.g. ".v5".
    repeated string swift_versions = 6;
  }
  // Optionally define the runtime libraries for the plugin.
  repeated RuntimeLibrary runtime_libraries = 1;
}

message PythonConfig {
  message RuntimeLibrary {
    // dependency_specification is a PEP 508 Dependency Specification.
    // Ref: https://peps.python.org/pep-0508/
    string dependency_specification = 1;
  }
  repeated RuntimeLibrary runtime_libraries = 1;
  // requires_python is a PEP 440 Version Specifier that specifies the value of
  // the `Requires-Python` field in a metadata file.
  //
  // Ref:
  // - https://packaging.python.org/en/latest/specifications/core-metadata/#requires-python
  // - https://peps.python.org/pep-0440/
  string requires_python = 2;
  // package_type is the PythonPackageType that this plugin generates.
  PythonPackageType package_type = 3;
}

// CargoConfig specifies the Cargo Registry configuration for a Rust plugin.
message CargoConfig {
  // RuntimeLibrary specifies a runtime dependency for a generated crate.
  // It is the subset of a full Cargo dependency specification, which contains
  // fields that are irrelevant for Generated SDKs.
  // Ref: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
  message RuntimeLibrary {
    // name specifies the name of the dependency.
    string name = 1;
    // version_requirement specifies the version requirement of the dependency.
    string version_requirement = 2;
    // default_features specifies whether or not default features will be enabled for the dependency.
    bool default_features = 3;
    // features specifies the features enabled for the dependency.
    repeated string features = 4;
  }
  // rust_version specifies the minimum supported Rust version (MSRV) for the generated crate.
  // Ref: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
  string rust_version = 1;
  // runtime_libraries specifies the runtime dependencies for the generated crate. Optional.
  repeated RuntimeLibrary runtime_libraries = 2;
}

// RegistryConfig is the configuration for the remote registry of a plugin.
message RegistryConfig {
  oneof registry_config {
    GoConfig go_config = 1;
    NPMConfig npm_config = 2;
    MavenConfig maven_config = 3;
    SwiftConfig swift_config = 4;
    PythonConfig python_config = 5;
    CargoConfig cargo_config = 6;
    NugetConfig nuget_config = 7;
    CmakeConfig cmake_config = 8;
  }
  // Reserved for future remote registry types.
  reserved 9;
  // The options to pass to the plugin. These will
  // be merged into a single, comma-separated string.
  repeated string options = 10;
}

message CuratedPluginReference {
  // The owner of the plugin, i.e. "library".
  string owner = 1;
  // The name of the plugin, i.e. "connect-go".
  string name = 2;
  // Semver-formatted plugin version.
  string version = 3;
  // The revision for this plugin version.
  uint32 revision = 4;
}

// CuratedPlugin represents a protoc plugin curated by Buf, such as protoc-gen-go.
message CuratedPlugin {
  // The ID of the plugin, which uniquely identifies the plugin.
  string id = 1;
  // The owner of the plugin, i.e. "library".
  string owner = 2;
  // The name of the plugin, i.e. "connect-go".
  string name = 3;
  // The optional registry type of the plugin.
  PluginRegistryType registry_type = 4;
  // Semver-formatted plugin version.
  string version = 5;
  // The full container image digest associated with this plugin version including
  // the algorithm.
  // Ref: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests
  string container_image_digest = 6;
  // The creation time of the plugin.
  google.protobuf.Timestamp create_time = 8;
  // List of plugin dependencies.
  repeated CuratedPluginReference dependencies = 9;
  // Optionally specify the URL leading to the source code of the plugin, if available.
  string source_url = 10;
  // Optionally specify a brief description of the plugin functionality.
  string description = 11;
  // The configuration for the remote registry of the plugin.
  RegistryConfig registry_config = 12;
  // The revision for this plugin version.
  uint32 revision = 13;
  // The output languages supported by the plugin.
  repeated PluginLanguage output_languages = 14;
  // spdx_license_id is the license of the plugin, which should be one of the identifiers
  // defined in https://spdx.org/licenses
  string spdx_license_id = 15;
  // license_url specifies an optional URL for the plugin's license (if not using a standard spdx_license_id).
  string license_url = 16;
  // verified indicates the plugin has been verified. Verification is a property
  // of the BSR and cannot be set by end-users.
  bool verified = 17;
  // Visibility indicates whether the plugin is public or private.
  CuratedPluginVisibility visibility = 18;
  // Deprecated indicates whether the plugin is deprecated.
  bool deprecated = 19;
  // Optionally specify a message to be displayed when the plugin is deprecated.
  string deprecation_message = 20;
  // The URL leading to the integration guide of the plugin, if available.
  string integration_guide_url = 21;
  // The configurable documentation of the Plugin.
  string doc = 22;
  // The collections the Plugin belongs to.
  repeated PluginCollection collections = 23;
}

// Plugin collections group related plugins, organizing them by functionality or ecosystem.
message PluginCollection {
  // The name of the collection.
  string name = 1;
}

// PluginCurationService manages curated plugins.
service PluginCurationService {
  // ListCuratedPlugins returns all the curated plugins available.
  rpc ListCuratedPlugins(ListCuratedPluginsRequest) returns (ListCuratedPluginsResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // CreateCuratedPlugin creates a new curated plugin.
  rpc CreateCuratedPlugin(CreateCuratedPluginRequest) returns (CreateCuratedPluginResponse) {
    option idempotency_level = IDEMPOTENT;
  }
  // GetLatestCuratedPlugin returns the latest version of a plugin matching given parameters.
  rpc GetLatestCuratedPlugin(GetLatestCuratedPluginRequest) returns (GetLatestCuratedPluginResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // DeleteCuratedPlugin deletes a curated plugin based on the given parameters.
  rpc DeleteCuratedPlugin(DeleteCuratedPluginRequest) returns (DeleteCuratedPluginResponse) {
    option idempotency_level = IDEMPOTENT;
  }
}

// CodeGenerationService generates code using remote plugins.
service CodeGenerationService {
  // GenerateCode generates code using the specified remote plugins.
  rpc GenerateCode(GenerateCodeRequest) returns (GenerateCodeResponse);
}

message GenerateCodeRequest {
  // The image to run plugins against to generate the desired file outputs.
  //
  // All image files that are not imports and not well-known types will be generated.
  // If you want to filter what files are generated, modify the image.
  // If you want to include imports, set include_imports.
  buf.alpha.image.v1.Image image = 1;
  repeated PluginGenerationRequest requests = 2;
  // Include imports from the Image in generation. If include_imports is also set
  // in one of requests, use the request's value for that plugin.
  bool include_imports = 3;
  // Include Well-Known Types from the Image in generation.
  //
  // include_imports must be set if include_well_known_types is set. If include_well_known_types
  // is also set in one of requests, use the request's value for that plugin.
  bool include_well_known_types = 4;
}

message GenerateCodeResponse {
  // Responses from each plugin execution.
  // The order of each response matches the order in the GenerateCodeRequest.
  repeated PluginGenerationResponse responses = 1;
}

// Request for performing code generation using the specified plugin.
message PluginGenerationRequest {
  // The plugin to execute.
  CuratedPluginReference plugin_reference = 1;
  // The options to pass to the plugin. These will
  // be merged into a single, comma-separated string.
  repeated string options = 2;
  // Include imports from the Image in generation.
  optional bool include_imports = 3;
  // Include Well-Known Types from the Image in generation.
  //
  // include_imports must be set if include_well_known_types is set.
  optional bool include_well_known_types = 4;
}

// Response from code generation for a given plugin.
message PluginGenerationResponse {
  // Generated code from the plugin.
  google.protobuf.compiler.CodeGeneratorResponse response = 1;
}

message DeleteCuratedPluginRequest {
  // The owner of the plugin to delete.
  string owner = 1;
  // The name of the plugin to delete.
  string name = 2;
  // Version is the plugin version and is optional. If this field is not set then delete all versions,
  // otherwise delete only the specified version which includes all revisions.
  string version = 3;
}

message DeleteCuratedPluginResponse {}

message CreateCuratedPluginRequest {
  // The owner of the plugin, i.e. "library".
  string owner = 1;
  // The name of the plugin, i.e. "connect-go".
  string name = 2;
  // The optional registry type of the plugin.
  PluginRegistryType registry_type = 3;
  // Semver-formatted plugin version.
  string version = 4;
  // The full container image digest associated with this plugin version including
  // the algorithm.
  // Ref: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests
  string container_image_digest = 5;
  // List of plugin dependencies.
  repeated CuratedPluginReference dependencies = 7;
  // The URL leading to the source code of the plugin, if available.
  string source_url = 8;
  // A brief description of the plugin functionality.
  string description = 9;
  // The configuration for the remote registry of the plugin.
  RegistryConfig registry_config = 12;
  // The revision for this plugin version.
  uint32 revision = 13;
  // The output languages supported by the plugin.
  repeated PluginLanguage output_languages = 14;
  // spdx_license_id is the license of the plugin, which should be one of the identifiers
  // defined in https://spdx.org/licenses
  string spdx_license_id = 15;
  // license_url specifies an optional URL for the plugin's license (if not using a standard spdx_license_id).
  string license_url = 16;
  // Visibility indicates whether the plugin is public or private.
  CuratedPluginVisibility visibility = 17;
  // The URL leading to the integration guide of the plugin, if available.
  string integration_guide_url = 18;
  // The deprecation status of the plugin.
  bool deprecated = 19;
}

message CreateCuratedPluginResponse {
  // The created plugin.
  CuratedPlugin configuration = 1;
}

message ListCuratedPluginsRequest {
  uint32 page_size = 1;
  // The first page is returned if this is empty.
  string page_token = 2;
  bool reverse = 3;
  // If true, will only return plugins which support remote packages (registry_type is set).
  bool supports_remote_packages = 4;
  // If true, will include deprecated plugins.
  bool include_deprecated = 5;
}

message ListCuratedPluginsResponse {
  repeated CuratedPlugin plugins = 1;
  // There are no more pages if this is empty.
  string next_page_token = 2;
}

message GetLatestCuratedPluginRequest {
  // The owner of the plugin, i.e. "library".
  string owner = 1;
  // The name of the plugin, i.e. "connect-go".
  string name = 2;
  // Both version (semver-formatted) and revision are optional, which means
  // return the latest plugin.
  // If version is set, but revision is omitted, then return the latest
  // revision for that version.
  // If version and revision are both set, return specific plugin.
  // It is an error to set a revision without a corresponding version.
  string version = 3;
  uint32 revision = 4;
  // If true, will only return versions (and revisions) which support remote packages (registry_type is set).
  bool supports_remote_packages = 5;
}

message GetLatestCuratedPluginResponse {
  CuratedPlugin plugin = 1;
  // versions is a semver-sorted list in descending order.
  repeated CuratedPluginVersionRevisions versions = 2;
}

message CuratedPluginVersionRevisions {
  string version = 1;
  // revisions is a sorted list in descending order.
  repeated uint32 revisions = 2;
}
