// Copyright 2025 Google LLC
//
// 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 google.cloud.managedkafka.schemaregistry.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";

option csharp_namespace = "Google.Cloud.ManagedKafka.SchemaRegistry.V1";
option go_package = "cloud.google.com/go/managedkafka/schemaregistry/apiv1/schemaregistrypb;schemaregistrypb";
option java_multiple_files = true;
option java_outer_classname = "SchemaRegistryResourcesProto";
option java_package = "com.google.cloud.managedkafka.schemaregistry.v1";
option php_namespace = "Google\\Cloud\\ManagedKafka\\SchemaRegistry\\V1";
option ruby_package = "Google::Cloud::ManagedKafka::SchemaRegistry::V1";

// SchemaRegistry is a schema registry instance.
message SchemaRegistry {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaRegistry"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}"
    plural: "schemaRegistries"
    singular: "schemaRegistry"
  };

  // Identifier. The name of the schema registry instance. Structured like:
  // `projects/{project}/locations/{location}/schemaRegistries/{schema_registry}`
  // The instance name {schema_registry} can contain the following:
  // * Up to 255 characters.
  // * Letters (uppercase or lowercase), numbers, and underscores.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The contexts of the schema registry instance.
  repeated string contexts = 2 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/SchemaContext"
    }
  ];
}

// Context represents an independent schema grouping in a schema registry
// instance.
message Context {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaContext"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}"
    plural: "contexts"
    singular: "context"
  };

  // Identifier. The name of the context. Structured like:
  // `projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}`
  // The context name {context} can contain the following:
  // * Up to 255 characters.
  // * Allowed characters: letters (uppercase or lowercase), numbers, and the
  // following special characters: `.`, `-`, `_`, `+`, `%`, and `~`.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Optional. The subjects of the context.
  repeated string subjects = 2 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/SchemaSubject"
    }
  ];
}

// Schema for a Kafka message.
message Schema {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/Schema"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/schemas/ids/{schema}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/schemas/ids/{schema}"
    plural: "schemas"
    singular: "schema"
  };

  // SchemaReference is a reference to a schema.
  message SchemaReference {
    // Required. The name of the reference.
    string name = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. The subject of the reference.
    string subject = 2 [(google.api.field_behavior) = REQUIRED];

    // Required. The version of the reference.
    int32 version = 3 [(google.api.field_behavior) = REQUIRED];
  }

  // Schema types.
  enum SchemaType {
    // No schema type. The default will be AVRO.
    SCHEMA_TYPE_UNSPECIFIED = 0;

    // Avro schema type.
    AVRO = 1;

    // JSON schema type.
    JSON = 2;

    // Protobuf schema type.
    PROTOBUF = 3;
  }

  // Optional. The schema type of the schema.
  SchemaType schema_type = 1 [(google.api.field_behavior) = OPTIONAL];

  // The schema payload.
  string schema_payload = 2 [json_name = "schema"];

  // Optional. The schema references used by the schema.
  repeated SchemaReference references = 3
      [(google.api.field_behavior) = OPTIONAL];
}

// Subject defines the evolution scope of schemas as a holder of schema
// versions.
message SchemaSubject {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaSubject"
    pattern: [
      "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/subjects/{subject}",
      "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/subjects/{subject}"
    ]
    singular: "subject"
    plural: "subjects"
  };

  // The name of the subject. Structured like:
  // `projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/subjects/{subject}`
  // or
  // `projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/subjects/{subject}`
  //
  // Subject name {subject} can contain the following:
  // * Up to 255 UTF-8 bytes.
  // * Allowed characters: letters (uppercase or lowercase), numbers, and the
  // following special characters: `.`, `-`, `_`, `+`, `%`, and `~`.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The versions of the subject.
  repeated string versions = 3 [
    (google.api.resource_reference).type =
        "managedkafka.googleapis.com/SchemaVersion",
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Version of a schema.
message SchemaVersion {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaVersion"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/subjects/{subject}/versions/{version}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/subjects/{subject}/versions/{version}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/compatibility/subjects/{subject}/versions"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/compatibility/subjects/{subject}/versions"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/compatibility/subjects/{subject}/versions/{version}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/compatibility/subjects/{subject}/versions/{version}"
    plural: "versions"
    singular: "version"
  };

  // Required. The subject of the version.
  string subject = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The version ID
  int32 version_id = 2
      [json_name = "version", (google.api.field_behavior) = REQUIRED];

  // Required. The schema ID.
  int32 schema_id = 3
      [json_name = "id", (google.api.field_behavior) = REQUIRED];

  // Optional. The schema type of the schema.
  Schema.SchemaType schema_type = 4 [(google.api.field_behavior) = OPTIONAL];

  // Required. The schema payload.
  string schema_payload = 5
      [json_name = "schema", (google.api.field_behavior) = REQUIRED];

  // Optional. The schema references used by the schema.
  repeated Schema.SchemaReference references = 6
      [(google.api.field_behavior) = OPTIONAL];
}

// SchemaConfig represents configuration for a schema registry or a specific
// subject.
message SchemaConfig {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaConfig"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/config"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/config/{subject}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/config"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/config/{subject}"
    plural: "configs"
    singular: "config"
  };

  // Compatibility type of the schemas.
  enum CompatibilityType {
    // No compatibility check.
    NONE = 0;

    // Backwards compatible with the most recent version.
    BACKWARD = 1;

    // Backwards compatible with all previous versions.
    BACKWARD_TRANSITIVE = 2;

    // Forwards compatible with the most recent version.
    FORWARD = 3;

    // Forwards compatible with all previous versions.
    FORWARD_TRANSITIVE = 4;

    // Backwards and forwards compatible with the most recent version.
    FULL = 5;

    // Backwards and forwards compatible with all previous versions.
    FULL_TRANSITIVE = 6;
  }

  // Required. The compatibility type of the schema.
  // The default value is BACKWARD.
  // If unset in a SchemaSubject-level SchemaConfig, defaults to the global
  // value. If unset in a SchemaRegistry-level SchemaConfig, reverts to the
  // default value.
  optional CompatibilityType compatibility = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. If true, the schema will be normalized before being stored or
  // looked up. The default is false. If unset in a SchemaSubject-level
  // SchemaConfig, the global value will be used. If unset in a
  // SchemaRegistry-level SchemaConfig, reverts to the default value.
  optional bool normalize = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The subject to which this subject is an alias of. Only applicable
  // for subject config.
  string alias = 3 [(google.api.field_behavior) = OPTIONAL];
}

// SchemaMode represents the mode of a schema registry or a specific subject.
// Four modes are supported:
// * NONE: deprecated. This was the default mode for a subject, but now the
// default is unset (which means use the global schema registry setting)
// * READONLY: The schema registry is in read-only mode.
// * READWRITE: The schema registry is in read-write mode, which allows limited
// write operations on the schema.
// * IMPORT: The schema registry is in import mode, which allows more editing
// operations on the schema for data importing purposes.
message SchemaMode {
  option (google.api.resource) = {
    type: "managedkafka.googleapis.com/SchemaMode"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/mode"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/mode/{subject}"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/mode"
    pattern: "projects/{project}/locations/{location}/schemaRegistries/{schema_registry}/contexts/{context}/mode/{subject}"
    plural: "modes"
    singular: "mode"
  };

  // Mode type of the schemas or subjects.
  enum ModeType {
    // The default / unset value.
    // The subject mode is NONE/unset by default, which means use the global
    // schema registry mode. This should not be used for setting the mode.
    NONE = 0;

    // READONLY mode.
    READONLY = 1;

    // READWRITE mode.
    READWRITE = 2;

    // IMPORT mode.
    IMPORT = 3;
  }

  // Required. The mode type of a schema registry (READWRITE by default) or of a
  // subject (unset by default, which means use the global schema registry
  // setting).
  ModeType mode = 1 [(google.api.field_behavior) = REQUIRED];
}
