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

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/servicedirectory/v1/endpoint.proto";
import "google/cloud/servicedirectory/v1/namespace.proto";
import "google/cloud/servicedirectory/v1/service.proto";
import "google/iam/v1/iam_policy.proto";
import "google/iam/v1/policy.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

option csharp_namespace = "Google.Cloud.ServiceDirectory.V1";
option go_package = "cloud.google.com/go/servicedirectory/apiv1/servicedirectorypb;servicedirectorypb";
option java_multiple_files = true;
option java_outer_classname = "RegistrationServiceProto";
option java_package = "com.google.cloud.servicedirectory.v1";
option php_namespace = "Google\\Cloud\\ServiceDirectory\\V1";
option ruby_package = "Google::Cloud::ServiceDirectory::V1";

// Service Directory API for registering services. It defines the following
// resource model:
//
// - The API has a collection of
// [Namespace][google.cloud.servicedirectory.v1.Namespace]
// resources, named `projects/*/locations/*/namespaces/*`.
//
// - Each Namespace has a collection of
// [Service][google.cloud.servicedirectory.v1.Service] resources, named
// `projects/*/locations/*/namespaces/*/services/*`.
//
// - Each Service has a collection of
// [Endpoint][google.cloud.servicedirectory.v1.Endpoint]
// resources, named
// `projects/*/locations/*/namespaces/*/services/*/endpoints/*`.
service RegistrationService {
  option (google.api.default_host) = "servicedirectory.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Creates a namespace, and returns the new namespace.
  rpc CreateNamespace(CreateNamespaceRequest) returns (Namespace) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/namespaces"
      body: "namespace"
    };
    option (google.api.method_signature) = "parent,namespace,namespace_id";
  }

  // Lists all namespaces.
  rpc ListNamespaces(ListNamespacesRequest) returns (ListNamespacesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/namespaces"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a namespace.
  rpc GetNamespace(GetNamespaceRequest) returns (Namespace) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/namespaces/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a namespace.
  rpc UpdateNamespace(UpdateNamespaceRequest) returns (Namespace) {
    option (google.api.http) = {
      patch: "/v1/{namespace.name=projects/*/locations/*/namespaces/*}"
      body: "namespace"
    };
    option (google.api.method_signature) = "namespace,update_mask";
  }

  // Deletes a namespace. This also deletes all services and endpoints in
  // the namespace.
  rpc DeleteNamespace(DeleteNamespaceRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/namespaces/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a service, and returns the new service.
  rpc CreateService(CreateServiceRequest) returns (Service) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/namespaces/*}/services"
      body: "service"
    };
    option (google.api.method_signature) = "parent,service,service_id";
  }

  // Lists all services belonging to a namespace.
  rpc ListServices(ListServicesRequest) returns (ListServicesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/namespaces/*}/services"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a service.
  rpc GetService(GetServiceRequest) returns (Service) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/namespaces/*/services/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a service.
  rpc UpdateService(UpdateServiceRequest) returns (Service) {
    option (google.api.http) = {
      patch: "/v1/{service.name=projects/*/locations/*/namespaces/*/services/*}"
      body: "service"
    };
    option (google.api.method_signature) = "service,update_mask";
  }

  // Deletes a service. This also deletes all endpoints associated with
  // the service.
  rpc DeleteService(DeleteServiceRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/namespaces/*/services/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates an endpoint, and returns the new endpoint.
  rpc CreateEndpoint(CreateEndpointRequest) returns (Endpoint) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/namespaces/*/services/*}/endpoints"
      body: "endpoint"
    };
    option (google.api.method_signature) = "parent,endpoint,endpoint_id";
  }

  // Lists all endpoints.
  rpc ListEndpoints(ListEndpointsRequest) returns (ListEndpointsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/namespaces/*/services/*}/endpoints"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an endpoint.
  rpc GetEndpoint(GetEndpointRequest) returns (Endpoint) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/namespaces/*/services/*/endpoints/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates an endpoint.
  rpc UpdateEndpoint(UpdateEndpointRequest) returns (Endpoint) {
    option (google.api.http) = {
      patch: "/v1/{endpoint.name=projects/*/locations/*/namespaces/*/services/*/endpoints/*}"
      body: "endpoint"
    };
    option (google.api.method_signature) = "endpoint,update_mask";
  }

  // Deletes an endpoint.
  rpc DeleteEndpoint(DeleteEndpointRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/namespaces/*/services/*/endpoints/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets the IAM Policy for a resource (namespace or service only).
  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/namespaces/*}:getIamPolicy"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/namespaces/*/services/*}:getIamPolicy"
        body: "*"
      }
    };
  }

  // Sets the IAM Policy for a resource (namespace or service only).
  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/namespaces/*}:setIamPolicy"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/namespaces/*/services/*}:setIamPolicy"
        body: "*"
      }
    };
  }

  // Tests IAM permissions for a resource (namespace or service only).
  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest)
      returns (google.iam.v1.TestIamPermissionsResponse) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/namespaces/*}:testIamPermissions"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/namespaces/*/services/*}:testIamPermissions"
        body: "*"
      }
    };
  }
}

// The request message for
// [RegistrationService.CreateNamespace][google.cloud.servicedirectory.v1.RegistrationService.CreateNamespace].
message CreateNamespaceRequest {
  // Required. The resource name of the project and location the namespace
  // will be created in.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The Resource ID must be 1-63 characters long, and comply with
  // <a href="https://www.ietf.org/rfc/rfc1035.txt" target="_blank">RFC1035</a>.
  // Specifically, the name must be 1-63 characters long and match the regular
  // expression `[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?` which means the first
  // character must be a lowercase letter, and all following characters must
  // be a dash, lowercase letter, or digit, except the last character, which
  // cannot be a dash.
  string namespace_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. A namespace with initial fields set.
  Namespace namespace = 3 [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces].
message ListNamespacesRequest {
  // Required. The resource name of the project and location whose namespaces
  // you'd like to list.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Optional. The maximum number of items to return.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The next_page_token value returned from a previous List request,
  // if any.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter to list results by.
  //
  // General `filter` string syntax:
  // `<field> <operator> <value> (<logical connector>)`
  //
  // *   `<field>` can be `name` or `labels.<key>` for map field
  // *   `<operator>` can be `<`, `>`, `<=`, `>=`, `!=`, `=`, `:`. Of which `:`
  //     means `HAS`, and is roughly the same as `=`
  // *   `<value>` must be the same data type as field
  // *   `<logical connector>` can be `AND`, `OR`, `NOT`
  //
  // Examples of valid filters:
  //
  // *   `labels.owner` returns namespaces that have a label with the key
  //     `owner`, this is the same as `labels:owner`
  // *   `labels.owner=sd` returns namespaces that have key/value
  //     `owner=sd`
  // *   `name>projects/my-project/locations/us-east1/namespaces/namespace-c`
  //     returns namespaces that have name that is alphabetically later than the
  //     string, so "namespace-e" is returned but "namespace-a" is not
  // *   `labels.owner!=sd AND labels.foo=bar` returns namespaces that have
  //     `owner` in label key but value is not `sd` AND have key/value `foo=bar`
  // *   `doesnotexist.foo=bar` returns an empty list. Note that namespace
  //     doesn't have a field called "doesnotexist". Since the filter does not
  //     match any namespaces, it returns no results
  //
  // For more information about filtering, see
  // [API Filtering](https://aip.dev/160).
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The order to list results by.
  //
  // General `order_by` string syntax: `<field> (<asc|desc>) (,)`
  //
  // *   `<field>` allows value: `name`
  // *   `<asc|desc>` ascending or descending order by `<field>`. If this is
  //     left blank, `asc` is used
  //
  // Note that an empty `order_by` string results in default order, which is
  // order by `name` in ascending order.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for
// [RegistrationService.ListNamespaces][google.cloud.servicedirectory.v1.RegistrationService.ListNamespaces].
message ListNamespacesResponse {
  // The list of namespaces.
  repeated Namespace namespaces = 1;

  // Token to retrieve the next page of results, or empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

// The request message for
// [RegistrationService.GetNamespace][google.cloud.servicedirectory.v1.RegistrationService.GetNamespace].
message GetNamespaceRequest {
  // Required. The name of the namespace to retrieve.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Namespace"
    }
  ];
}

// The request message for
// [RegistrationService.UpdateNamespace][google.cloud.servicedirectory.v1.RegistrationService.UpdateNamespace].
message UpdateNamespaceRequest {
  // Required. The updated namespace.
  Namespace namespace = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. List of fields to be updated in this request.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.DeleteNamespace][google.cloud.servicedirectory.v1.RegistrationService.DeleteNamespace].
message DeleteNamespaceRequest {
  // Required. The name of the namespace to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Namespace"
    }
  ];
}

// The request message for
// [RegistrationService.CreateService][google.cloud.servicedirectory.v1.RegistrationService.CreateService].
message CreateServiceRequest {
  // Required. The resource name of the namespace this service will belong to.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Namespace"
    }
  ];

  // Required. The Resource ID must be 1-63 characters long, and comply with
  // <a href="https://www.ietf.org/rfc/rfc1035.txt" target="_blank">RFC1035</a>.
  // Specifically, the name must be 1-63 characters long and match the regular
  // expression `[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?` which means the first
  // character must be a lowercase letter, and all following characters must
  // be a dash, lowercase letter, or digit, except the last character, which
  // cannot be a dash.
  string service_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. A service  with initial fields set.
  Service service = 3 [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices].
message ListServicesRequest {
  // Required. The resource name of the namespace whose services you'd
  // like to list.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Namespace"
    }
  ];

  // Optional. The maximum number of items to return.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The next_page_token value returned from a previous List request,
  // if any.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter to list results by.
  //
  // General `filter` string syntax:
  // `<field> <operator> <value> (<logical connector>)`
  //
  // *   `<field>` can be `name` or `annotations.<key>` for map field
  // *   `<operator>` can be `<`, `>`, `<=`, `>=`, `!=`, `=`, `:`. Of which `:`
  //     means `HAS`, and is roughly the same as `=`
  // *   `<value>` must be the same data type as field
  // *   `<logical connector>` can be `AND`, `OR`, `NOT`
  //
  // Examples of valid filters:
  //
  // *   `annotations.owner` returns services that have a annotation with the
  //     key `owner`, this is the same as `annotations:owner`
  // *   `annotations.protocol=gRPC` returns services that have key/value
  //     `protocol=gRPC`
  // *
  // `name>projects/my-project/locations/us-east1/namespaces/my-namespace/services/service-c`
  //     returns services that have name that is alphabetically later than the
  //     string, so "service-e" is returned but "service-a" is not
  // *   `annotations.owner!=sd AND annotations.foo=bar` returns services that
  //     have `owner` in annotation key but value is not `sd` AND have
  //     key/value `foo=bar`
  // *   `doesnotexist.foo=bar` returns an empty list. Note that service
  //     doesn't have a field called "doesnotexist". Since the filter does not
  //     match any services, it returns no results
  //
  // For more information about filtering, see
  // [API Filtering](https://aip.dev/160).
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The order to list results by.
  //
  // General `order_by` string syntax: `<field> (<asc|desc>) (,)`
  //
  // *   `<field>` allows value: `name`
  // *   `<asc|desc>` ascending or descending order by `<field>`. If this is
  //     left blank, `asc` is used
  //
  // Note that an empty `order_by` string results in default order, which is
  // order by `name` in ascending order.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for
// [RegistrationService.ListServices][google.cloud.servicedirectory.v1.RegistrationService.ListServices].
message ListServicesResponse {
  // The list of services.
  repeated Service services = 1;

  // Token to retrieve the next page of results, or empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

// The request message for
// [RegistrationService.GetService][google.cloud.servicedirectory.v1.RegistrationService.GetService].
// This should not be used for looking up a service. Instead, use the `resolve`
// method as it contains all endpoints and associated annotations.
message GetServiceRequest {
  // Required. The name of the service to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Service"
    }
  ];
}

// The request message for
// [RegistrationService.UpdateService][google.cloud.servicedirectory.v1.RegistrationService.UpdateService].
message UpdateServiceRequest {
  // Required. The updated service.
  Service service = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. List of fields to be updated in this request.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.DeleteService][google.cloud.servicedirectory.v1.RegistrationService.DeleteService].
message DeleteServiceRequest {
  // Required. The name of the service to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Service"
    }
  ];
}

// The request message for
// [RegistrationService.CreateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.CreateEndpoint].
message CreateEndpointRequest {
  // Required. The resource name of the service that this endpoint provides.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Service"
    }
  ];

  // Required. The Resource ID must be 1-63 characters long, and comply with
  // <a href="https://www.ietf.org/rfc/rfc1035.txt" target="_blank">RFC1035</a>.
  // Specifically, the name must be 1-63 characters long and match the regular
  // expression `[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?` which means the first
  // character must be a lowercase letter, and all following characters must
  // be a dash, lowercase letter, or digit, except the last character, which
  // cannot be a dash.
  string endpoint_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. A endpoint with initial fields set.
  Endpoint endpoint = 3 [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints].
message ListEndpointsRequest {
  // Required. The resource name of the service whose endpoints you'd like to
  // list.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Service"
    }
  ];

  // Optional. The maximum number of items to return.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The next_page_token value returned from a previous List request,
  // if any.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter to list results by.
  //
  // General `filter` string syntax:
  // `<field> <operator> <value> (<logical connector>)`
  //
  // *   `<field>` can be `name`, `address`, `port`, or `annotations.<key>` for
  //      map field
  // *   `<operator>` can be `<`, `>`, `<=`, `>=`, `!=`, `=`, `:`. Of which `:`
  //     means `HAS`, and is roughly the same as `=`
  // *   `<value>` must be the same data type as field
  // *   `<logical connector>` can be `AND`, `OR`, `NOT`
  //
  // Examples of valid filters:
  //
  // *   `annotations.owner` returns endpoints that have a annotation with the
  //     key `owner`, this is the same as `annotations:owner`
  // *   `annotations.protocol=gRPC` returns endpoints that have key/value
  //     `protocol=gRPC`
  // *   `address=192.108.1.105` returns endpoints that have this address
  // *   `port>8080` returns endpoints that have port number larger than 8080
  // *
  // `name>projects/my-project/locations/us-east1/namespaces/my-namespace/services/my-service/endpoints/endpoint-c`
  //     returns endpoints that have name that is alphabetically later than the
  //     string, so "endpoint-e" is returned but "endpoint-a" is not
  // *   `annotations.owner!=sd AND annotations.foo=bar` returns endpoints that
  //     have `owner` in annotation key but value is not `sd` AND have
  //     key/value `foo=bar`
  // *   `doesnotexist.foo=bar` returns an empty list. Note that endpoint
  //     doesn't have a field called "doesnotexist". Since the filter does not
  //     match any endpoints, it returns no results
  //
  // For more information about filtering, see
  // [API Filtering](https://aip.dev/160).
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The order to list results by.
  //
  // General `order_by` string syntax: `<field> (<asc|desc>) (,)`
  //
  // *   `<field>` allows values: `name`, `address`, `port`
  // *   `<asc|desc>` ascending or descending order by `<field>`. If this is
  //     left blank, `asc` is used
  //
  // Note that an empty `order_by` string results in default order, which is
  // order by `name` in ascending order.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for
// [RegistrationService.ListEndpoints][google.cloud.servicedirectory.v1.RegistrationService.ListEndpoints].
message ListEndpointsResponse {
  // The list of endpoints.
  repeated Endpoint endpoints = 1;

  // Token to retrieve the next page of results, or empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

// The request message for
// [RegistrationService.GetEndpoint][google.cloud.servicedirectory.v1.RegistrationService.GetEndpoint].
// This should not be used to lookup endpoints at runtime. Instead, use
// the `resolve` method.
message GetEndpointRequest {
  // Required. The name of the endpoint to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Endpoint"
    }
  ];
}

// The request message for
// [RegistrationService.UpdateEndpoint][google.cloud.servicedirectory.v1.RegistrationService.UpdateEndpoint].
message UpdateEndpointRequest {
  // Required. The updated endpoint.
  Endpoint endpoint = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. List of fields to be updated in this request.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The request message for
// [RegistrationService.DeleteEndpoint][google.cloud.servicedirectory.v1.RegistrationService.DeleteEndpoint].
message DeleteEndpointRequest {
  // Required. The name of the endpoint to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "servicedirectory.googleapis.com/Endpoint"
    }
  ];
}
