// 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.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/cloud/managedkafka/v1/resources.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

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

// The service that a client application uses to manage Apache Kafka clusters,
// topics and consumer groups.
service ManagedKafka {
  option (google.api.default_host) = "managedkafka.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists the clusters in a given project and location.
  rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/clusters"
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns the properties of a single cluster.
  rpc GetCluster(GetClusterRequest) returns (Cluster) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/clusters/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new cluster in a given project and location.
  rpc CreateCluster(CreateClusterRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/clusters"
      body: "cluster"
    };
    option (google.api.method_signature) = "parent,cluster,cluster_id";
    option (google.longrunning.operation_info) = {
      response_type: "Cluster"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates the properties of a single cluster.
  rpc UpdateCluster(UpdateClusterRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{cluster.name=projects/*/locations/*/clusters/*}"
      body: "cluster"
    };
    option (google.api.method_signature) = "cluster,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Cluster"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a single cluster.
  rpc DeleteCluster(DeleteClusterRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/clusters/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists the topics in a given cluster.
  rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/clusters/*}/topics"
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns the properties of a single topic.
  rpc GetTopic(GetTopicRequest) returns (Topic) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/clusters/*/topics/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new topic in a given project and location.
  rpc CreateTopic(CreateTopicRequest) returns (Topic) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/clusters/*}/topics"
      body: "topic"
    };
    option (google.api.method_signature) = "parent,topic,topic_id";
  }

  // Updates the properties of a single topic.
  rpc UpdateTopic(UpdateTopicRequest) returns (Topic) {
    option (google.api.http) = {
      patch: "/v1/{topic.name=projects/*/locations/*/clusters/*/topics/*}"
      body: "topic"
    };
    option (google.api.method_signature) = "topic,update_mask";
  }

  // Deletes a single topic.
  rpc DeleteTopic(DeleteTopicRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/clusters/*/topics/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists the consumer groups in a given cluster.
  rpc ListConsumerGroups(ListConsumerGroupsRequest)
      returns (ListConsumerGroupsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/clusters/*}/consumerGroups"
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns the properties of a single consumer group.
  rpc GetConsumerGroup(GetConsumerGroupRequest) returns (ConsumerGroup) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/clusters/*/consumerGroups/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates the properties of a single consumer group.
  rpc UpdateConsumerGroup(UpdateConsumerGroupRequest) returns (ConsumerGroup) {
    option (google.api.http) = {
      patch: "/v1/{consumer_group.name=projects/*/locations/*/clusters/*/consumerGroups/**}"
      body: "consumer_group"
    };
    option (google.api.method_signature) = "consumer_group,update_mask";
  }

  // Deletes a single consumer group.
  rpc DeleteConsumerGroup(DeleteConsumerGroupRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/clusters/*/consumerGroups/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists the acls in a given cluster.
  rpc ListAcls(ListAclsRequest) returns (ListAclsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/clusters/*}/acls"
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns the properties of a single acl.
  rpc GetAcl(GetAclRequest) returns (Acl) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/clusters/*/acls/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new acl in the given project, location, and cluster.
  rpc CreateAcl(CreateAclRequest) returns (Acl) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/clusters/*}/acls"
      body: "acl"
    };
    option (google.api.method_signature) = "parent,acl,acl_id";
  }

  // Updates the properties of a single acl.
  rpc UpdateAcl(UpdateAclRequest) returns (Acl) {
    option (google.api.http) = {
      patch: "/v1/{acl.name=projects/*/locations/*/clusters/*/acls/**}"
      body: "acl"
    };
    option (google.api.method_signature) = "acl,update_mask";
  }

  // Deletes an acl.
  rpc DeleteAcl(DeleteAclRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/clusters/*/acls/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Incremental update: Adds an acl entry to an acl. Creates the acl if it does
  // not exist yet.
  rpc AddAclEntry(AddAclEntryRequest) returns (AddAclEntryResponse) {
    option (google.api.http) = {
      post: "/v1/{acl=projects/*/locations/*/clusters/*/acls/**}:addAclEntry"
      body: "acl_entry"
    };
    option (google.api.method_signature) = "acl,acl_entry";
  }

  // Incremental update: Removes an acl entry from an acl. Deletes the acl if
  // its acl entries become empty (i.e. if the removed entry was the last one in
  // the acl).
  rpc RemoveAclEntry(RemoveAclEntryRequest) returns (RemoveAclEntryResponse) {
    option (google.api.http) = {
      post: "/v1/{acl=projects/*/locations/*/clusters/*/acls/**}:removeAclEntry"
      body: "acl_entry"
    };
    option (google.api.method_signature) = "acl,acl_entry";
  }
}

// Request for ListClusters.
message ListClustersRequest {
  // Required. The parent location whose clusters are to be listed. Structured
  // like `projects/{project}/locations/{location}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Cluster"
    }
  ];

  // Optional. The maximum number of clusters to return. The service may return
  // fewer than this value. If unspecified, server will pick an appropriate
  // default.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListClusters` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListClusters` must match
  // the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Filter expression for the result.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Order by fields for the result.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response for ListClusters.
message ListClustersResponse {
  // The list of Clusters in the requested parent.
  repeated Cluster clusters = 1;

  // A token that can be sent as `page_token` to retrieve the next page of
  // results. If this field is omitted, there are no more results.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// Request for GetCluster.
message GetClusterRequest {
  // Required. The name of the cluster whose configuration to return.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Cluster"
    }
  ];
}

// Request for CreateCluster.
message CreateClusterRequest {
  // Required. The parent region in which to create the cluster. Structured like
  // `projects/{project}/locations/{location}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Cluster"
    }
  ];

  // Required. The ID to use for the cluster, which will become the final
  // component of the cluster's name. The ID must be 1-63 characters long, and
  // match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` to comply with
  // RFC 1035.
  //
  // This value is structured like: `my-cluster-id`.
  string cluster_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Configuration of the cluster to create. Its `name` field is
  // ignored.
  Cluster cluster = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID to avoid duplication of requests. If a request times out or
  // fails, retrying with the same ID allows the server to recognize the
  // previous attempt. For at least 60 minutes, the server ignores duplicate
  // requests bearing the same ID.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID
  // within 60 minutes of the last request, the server checks if an original
  // operation with the same request ID was received. If so, the server ignores
  // the second request.
  //
  // The request ID must be a valid UUID. A zero UUID is not supported
  // (00000000-0000-0000-0000-000000000000).
  string request_id = 4 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request for UpdateCluster.
message UpdateClusterRequest {
  // Required. Field mask is used to specify the fields to be overwritten in the
  // cluster resource by the update. The fields specified in the update_mask are
  // relative to the resource, not the full request. A field will be overwritten
  // if it is in the mask. The mask is required and a value of * will update all
  // fields.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The cluster to update. Its `name` field must be populated.
  Cluster cluster = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID to avoid duplication of requests. If a request times out or
  // fails, retrying with the same ID allows the server to recognize the
  // previous attempt. For at least 60 minutes, the server ignores duplicate
  // requests bearing the same ID.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID
  // within 60 minutes of the last request, the server checks if an original
  // operation with the same request ID was received. If so, the server ignores
  // the second request.
  //
  // The request ID must be a valid UUID. A zero UUID is not supported
  // (00000000-0000-0000-0000-000000000000).
  string request_id = 3 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request for DeleteCluster.
message DeleteClusterRequest {
  // Required. The name of the cluster to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Cluster"
    }
  ];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID to avoid duplication of requests. If a request times out or
  // fails, retrying with the same ID allows the server to recognize the
  // previous attempt. For at least 60 minutes, the server ignores duplicate
  // requests bearing the same ID.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID
  // within 60 minutes of the last request, the server checks if an original
  // operation with the same request ID was received. If so, the server ignores
  // the second request.
  //
  // The request ID must be a valid UUID. A zero UUID is not supported
  // (00000000-0000-0000-0000-000000000000).
  string request_id = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request for ListTopics.
message ListTopicsRequest {
  // Required. The parent cluster whose topics are to be listed. Structured like
  // `projects/{project}/locations/{location}/clusters/{cluster}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Topic"
    }
  ];

  // Optional. The maximum number of topics to return. The service may return
  // fewer than this value. If unset or zero, all topics for the parent is
  // returned.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListTopics` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListTopics` must match
  // the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response for ListTopics.
message ListTopicsResponse {
  // The list of topics in the requested parent. The order of the topics is
  // unspecified.
  repeated Topic topics = 1;

  // A token that can be sent as `page_token` to retrieve the next page of
  // results. If this field is omitted, there are no more results.
  string next_page_token = 2;
}

// Request for GetTopic.
message GetTopicRequest {
  // Required. The name of the topic whose configuration to return. Structured
  // like:
  // projects/{project}/locations/{location}/clusters/{cluster}/topics/{topic}.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Topic"
    }
  ];
}

// Request for CreateTopic.
message CreateTopicRequest {
  // Required. The parent cluster in which to create the topic.
  // Structured like
  // `projects/{project}/locations/{location}/clusters/{cluster}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Topic"
    }
  ];

  // Required. The ID to use for the topic, which will become the final
  // component of the topic's name.
  //
  // This value is structured like: `my-topic-name`.
  string topic_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Configuration of the topic to create. Its `name` field is
  // ignored.
  Topic topic = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request for UpdateTopic.
message UpdateTopicRequest {
  // Required. Field mask is used to specify the fields to be overwritten in the
  // Topic resource by the update. The fields specified in the update_mask are
  // relative to the resource, not the full request. A field will be overwritten
  // if it is in the mask. The mask is required and a value of * will update all
  // fields.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The topic to update. Its `name` field must be populated.
  Topic topic = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request for DeleteTopic.
message DeleteTopicRequest {
  // Required. The name of the topic to delete.
  // `projects/{project}/locations/{location}/clusters/{cluster}/topics/{topic}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Topic"
    }
  ];
}

// Request for ListConsumerGroups.
message ListConsumerGroupsRequest {
  // Required. The parent cluster whose consumer groups are to be listed.
  // Structured like
  // `projects/{project}/locations/{location}/clusters/{cluster}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/ConsumerGroup"
    }
  ];

  // Optional. The maximum number of consumer groups to return. The service may
  // return fewer than this value. If unset or zero, all consumer groups for the
  // parent is returned.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListConsumerGroups` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListConsumerGroups` must
  // match the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response for ListConsumerGroups.
message ListConsumerGroupsResponse {
  // The list of consumer group in the requested parent. The order of the
  // consumer groups is unspecified.
  repeated ConsumerGroup consumer_groups = 1;

  // A token that can be sent as `page_token` to retrieve the next page of
  // results. If this field is omitted, there are no more results.
  string next_page_token = 2;
}

// Request for GetConsumerGroup.
message GetConsumerGroupRequest {
  // Required. The name of the consumer group whose configuration to return.
  // `projects/{project}/locations/{location}/clusters/{cluster}/consumerGroups/{consumerGroup}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/ConsumerGroup"
    }
  ];
}

// Request for UpdateConsumerGroup.
message UpdateConsumerGroupRequest {
  // Required. Field mask is used to specify the fields to be overwritten in the
  // ConsumerGroup resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. The
  // mask is required and a value of * will update all fields.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The consumer group to update. Its `name` field must be populated.
  ConsumerGroup consumer_group = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request for DeleteConsumerGroup.
message DeleteConsumerGroupRequest {
  // Required. The name of the consumer group to delete.
  // `projects/{project}/locations/{location}/clusters/{cluster}/consumerGroups/{consumerGroup}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/ConsumerGroup"
    }
  ];
}

// Request for ListAcls.
message ListAclsRequest {
  // Required. The parent cluster whose acls are to be listed.
  // Structured like
  // `projects/{project}/locations/{location}/clusters/{cluster}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Acl"
    }
  ];

  // Optional. The maximum number of acls to return. The service may return
  // fewer than this value. If unset or zero, all acls for the parent is
  // returned.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListAcls` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListAcls` must match
  // the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response for ListAcls.
message ListAclsResponse {
  // The list of acls in the requested parent. The order of the acls is
  // unspecified.
  repeated Acl acls = 1;

  // A token that can be sent as `page_token` to retrieve the next page of
  // results. If this field is omitted, there are no more results.
  string next_page_token = 2;
}

// Request for GetAcl.
message GetAclRequest {
  // Required. The name of the acl to return.
  // Structured like:
  // `projects/{project}/locations/{location}/clusters/{cluster}/acls/{acl_id}`.
  //
  // The structure of `acl_id` defines the Resource Pattern (resource_type,
  // resource_name, pattern_type) of the acl. See `Acl.name` for
  // details.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Acl"
    }
  ];
}

// Request for CreateAcl.
message CreateAclRequest {
  // Required. The parent cluster in which to create the acl.
  // Structured like
  // `projects/{project}/locations/{location}/clusters/{cluster}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "managedkafka.googleapis.com/Acl"
    }
  ];

  // Required. The ID to use for the acl, which will become the final component
  // of the acl's name. The structure of `acl_id` defines the Resource Pattern
  // (resource_type, resource_name, pattern_type) of the acl. `acl_id` is
  // structured like one of the following:
  //
  // For acls on the cluster:
  //   `cluster`
  //
  // For acls on a single resource within the cluster:
  //   `topic/{resource_name}`
  //   `consumerGroup/{resource_name}`
  //   `transactionalId/{resource_name}`
  //
  // For acls on all resources that match a prefix:
  //   `topicPrefixed/{resource_name}`
  //   `consumerGroupPrefixed/{resource_name}`
  //   `transactionalIdPrefixed/{resource_name}`
  //
  // For acls on all resources of a given type (i.e. the wildcard literal "*"):
  //   `allTopics` (represents `topic/*`)
  //   `allConsumerGroups` (represents `consumerGroup/*`)
  //   `allTransactionalIds` (represents `transactionalId/*`)
  string acl_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Configuration of the acl to create. Its `name` field is ignored.
  Acl acl = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request for UpdateAcl.
message UpdateAclRequest {
  // Required. The updated acl. Its `name` and `etag` fields must be populated.
  // `acl_entries` must not be empty in the updated acl; to remove all acl
  // entries for an acl, use DeleteAcl.
  Acl acl = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Field mask is used to specify the fields to be overwritten in the
  // Acl resource by the update. The fields specified in the update_mask are
  // relative to the resource, not the full request. A field will be overwritten
  // if it is in the mask.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Request for DeleteAcl.
message DeleteAclRequest {
  // Required. The name of the acl to delete.
  // Structured like:
  // `projects/{project}/locations/{location}/clusters/{cluster}/acls/{acl_id}`.
  //
  // The structure of `acl_id` defines the Resource Pattern (resource_type,
  // resource_name, pattern_type) of the acl. See `Acl.name` for details.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Acl"
    }
  ];
}

// Request for AddAclEntry.
message AddAclEntryRequest {
  // Required. The name of the acl to add the acl entry to.
  // Structured like:
  // `projects/{project}/locations/{location}/clusters/{cluster}/acls/{acl_id}`.
  //
  // The structure of `acl_id` defines the Resource Pattern (resource_type,
  // resource_name, pattern_type) of the acl. See `Acl.name` for
  // details.
  string acl = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Acl"
    }
  ];

  // Required. The acl entry to add.
  AclEntry acl_entry = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response for AddAclEntry.
message AddAclEntryResponse {
  // The updated acl.
  Acl acl = 1;

  // Whether the acl was created as a result of adding the acl entry.
  bool acl_created = 2;
}

// Request for RemoveAclEntry.
message RemoveAclEntryRequest {
  // Required. The name of the acl to remove the acl entry from.
  // Structured like:
  // `projects/{project}/locations/{location}/clusters/{cluster}/acls/{acl_id}`.
  //
  // The structure of `acl_id` defines the Resource Pattern (resource_type,
  // resource_name, pattern_type) of the acl. See `Acl.name` for
  // details.
  string acl = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "managedkafka.googleapis.com/Acl"
    }
  ];

  // Required. The acl entry to remove.
  AclEntry acl_entry = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response for RemoveAclEntry.
message RemoveAclEntryResponse {
  // The result of removing the acl entry, depending on whether the acl was
  // deleted as a result of removing the acl entry.
  oneof result {
    // The updated acl. Returned if the removed acl entry was not the last entry
    // in the acl.
    Acl acl = 1;

    // Returned with value true if the removed acl entry was the last entry in
    // the acl, resulting in acl deletion.
    bool acl_deleted = 2;
  }
}
