// 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.dataplex.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/dataplex/v1/service.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Dataplex.V1";
option go_package = "cloud.google.com/go/dataplex/apiv1/dataplexpb;dataplexpb";
option java_multiple_files = true;
option java_outer_classname = "CatalogProto";
option java_package = "com.google.cloud.dataplex.v1";
option php_namespace = "Google\\Cloud\\Dataplex\\V1";
option ruby_package = "Google::Cloud::Dataplex::V1";

// The primary resources offered by this service are EntryGroups, EntryTypes,
// AspectTypes, and Entries. They collectively let data administrators organize,
// manage, secure, and catalog data located across cloud projects in their
// organization in a variety of storage systems, including Cloud Storage and
// BigQuery.
service CatalogService {
  option (google.api.default_host) = "dataplex.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Creates an EntryType.
  rpc CreateEntryType(CreateEntryTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/entryTypes"
      body: "entry_type"
    };
    option (google.api.method_signature) = "parent,entry_type,entry_type_id";
    option (google.longrunning.operation_info) = {
      response_type: "EntryType"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates an EntryType.
  rpc UpdateEntryType(UpdateEntryTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{entry_type.name=projects/*/locations/*/entryTypes/*}"
      body: "entry_type"
    };
    option (google.api.method_signature) = "entry_type,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "EntryType"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes an EntryType.
  rpc DeleteEntryType(DeleteEntryTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/entryTypes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists EntryType resources in a project and location.
  rpc ListEntryTypes(ListEntryTypesRequest) returns (ListEntryTypesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/entryTypes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an EntryType.
  rpc GetEntryType(GetEntryTypeRequest) returns (EntryType) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/entryTypes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates an AspectType.
  rpc CreateAspectType(CreateAspectTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/aspectTypes"
      body: "aspect_type"
    };
    option (google.api.method_signature) = "parent,aspect_type,aspect_type_id";
    option (google.longrunning.operation_info) = {
      response_type: "AspectType"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates an AspectType.
  rpc UpdateAspectType(UpdateAspectTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{aspect_type.name=projects/*/locations/*/aspectTypes/*}"
      body: "aspect_type"
    };
    option (google.api.method_signature) = "aspect_type,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "AspectType"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes an AspectType.
  rpc DeleteAspectType(DeleteAspectTypeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/aspectTypes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists AspectType resources in a project and location.
  rpc ListAspectTypes(ListAspectTypesRequest)
      returns (ListAspectTypesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/aspectTypes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an AspectType.
  rpc GetAspectType(GetAspectTypeRequest) returns (AspectType) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/aspectTypes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates an EntryGroup.
  rpc CreateEntryGroup(CreateEntryGroupRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/entryGroups"
      body: "entry_group"
    };
    option (google.api.method_signature) = "parent,entry_group,entry_group_id";
    option (google.longrunning.operation_info) = {
      response_type: "EntryGroup"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates an EntryGroup.
  rpc UpdateEntryGroup(UpdateEntryGroupRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{entry_group.name=projects/*/locations/*/entryGroups/*}"
      body: "entry_group"
    };
    option (google.api.method_signature) = "entry_group,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "EntryGroup"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes an EntryGroup.
  rpc DeleteEntryGroup(DeleteEntryGroupRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/entryGroups/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists EntryGroup resources in a project and location.
  rpc ListEntryGroups(ListEntryGroupsRequest)
      returns (ListEntryGroupsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/entryGroups"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an EntryGroup.
  rpc GetEntryGroup(GetEntryGroupRequest) returns (EntryGroup) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/entryGroups/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates an Entry.
  rpc CreateEntry(CreateEntryRequest) returns (Entry) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/entryGroups/*}/entries"
      body: "entry"
    };
    option (google.api.method_signature) = "parent,entry,entry_id";
  }

  // Updates an Entry.
  rpc UpdateEntry(UpdateEntryRequest) returns (Entry) {
    option (google.api.http) = {
      patch: "/v1/{entry.name=projects/*/locations/*/entryGroups/*/entries/**}"
      body: "entry"
    };
    option (google.api.method_signature) = "entry,update_mask";
  }

  // Deletes an Entry.
  rpc DeleteEntry(DeleteEntryRequest) returns (Entry) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/entryGroups/*/entries/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists Entries within an EntryGroup.
  rpc ListEntries(ListEntriesRequest) returns (ListEntriesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/entryGroups/*}/entries"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an Entry.
  rpc GetEntry(GetEntryRequest) returns (Entry) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/entryGroups/*/entries/**}"
    };
    option (google.api.method_signature) = "name";
  }

  // Looks up an entry by name using the permission on the source system.
  rpc LookupEntry(LookupEntryRequest) returns (Entry) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*}:lookupEntry"
    };
  }

  // Searches for Entries matching the given query and scope.
  rpc SearchEntries(SearchEntriesRequest) returns (SearchEntriesResponse) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*}:searchEntries"
    };
    option (google.api.method_signature) = "name,query";
  }

  // Creates a metadata job. For example, use a metadata job to import Dataplex
  // Catalog entries and aspects from a third-party system into Dataplex.
  rpc CreateMetadataJob(CreateMetadataJobRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/metadataJobs"
      body: "metadata_job"
    };
    option (google.api.method_signature) =
        "parent,metadata_job,metadata_job_id";
    option (google.longrunning.operation_info) = {
      response_type: "MetadataJob"
      metadata_type: "OperationMetadata"
    };
  }

  // Gets a metadata job.
  rpc GetMetadataJob(GetMetadataJobRequest) returns (MetadataJob) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/metadataJobs/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists metadata jobs.
  rpc ListMetadataJobs(ListMetadataJobsRequest)
      returns (ListMetadataJobsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/metadataJobs"
    };
    option (google.api.method_signature) = "parent";
  }

  // Cancels a metadata job.
  //
  // If you cancel a metadata import job that is in progress, the changes in the
  // job might be partially applied. We recommend that you reset the state of
  // the entry groups in your project by running another metadata job that
  // reverts the changes from the canceled job.
  rpc CancelMetadataJob(CancelMetadataJobRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/metadataJobs/*}:cancel"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }
}

// AspectType is a template for creating Aspects, and represents the
// JSON-schema for a given Entry, for example, BigQuery Table Schema.
message AspectType {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/AspectType"
    pattern: "projects/{project}/locations/{location}/aspectTypes/{aspect_type}"
    plural: "aspectTypes"
    singular: "aspectType"
  };

  // Autorization for an AspectType.
  message Authorization {
    // Immutable. The IAM permission grantable on the EntryGroup to allow access
    // to instantiate Aspects of Dataplex owned AspectTypes, only settable for
    // Dataplex owned Types.
    string alternate_use_permission = 1
        [(google.api.field_behavior) = IMMUTABLE];
  }

  // MetadataTemplate definition for an AspectType.
  message MetadataTemplate {
    // Definition of Enumvalue, to be used for enum fields.
    message EnumValue {
      // Required. Index for the enum value. It can't be modified.
      int32 index = 1 [(google.api.field_behavior) = REQUIRED];

      // Required. Name of the enumvalue. This is the actual value that the
      // aspect can contain.
      string name = 2 [(google.api.field_behavior) = REQUIRED];

      // Optional. You can set this message if you need to deprecate an enum
      // value.
      string deprecated = 3 [(google.api.field_behavior) = OPTIONAL];
    }

    // Definition of the constraints of a field.
    message Constraints {
      // Optional. Marks this field as optional or required.
      bool required = 1 [(google.api.field_behavior) = OPTIONAL];
    }

    // Definition of the annotations of a field.
    message Annotations {
      // Optional. Marks a field as deprecated. You can include a deprecation
      // message.
      string deprecated = 1 [(google.api.field_behavior) = OPTIONAL];

      // Optional. Display name for a field.
      string display_name = 2 [(google.api.field_behavior) = OPTIONAL];

      // Optional. Description for a field.
      string description = 3 [(google.api.field_behavior) = OPTIONAL];

      // Optional. Display order for a field. You can use this to reorder where
      // a field is rendered.
      int32 display_order = 4 [(google.api.field_behavior) = OPTIONAL];

      // Optional. You can use String Type annotations to specify special
      // meaning to string fields. The following values are supported:
      //
      // * richText: The field must be interpreted as a rich text field.
      // * url: A fully qualified URL link.
      // * resource: A service qualified resource reference.
      string string_type = 6 [(google.api.field_behavior) = OPTIONAL];

      // Optional. Suggested hints for string fields. You can use them to
      // suggest values to users through console.
      repeated string string_values = 7
          [(google.api.field_behavior) = OPTIONAL];
    }

    // Optional. Index is used to encode Template messages. The value of index
    // can range between 1 and 2,147,483,647. Index must be unique within all
    // fields in a Template. (Nested Templates can reuse indexes). Once a
    // Template is defined, the index cannot be changed, because it identifies
    // the field in the actual storage format. Index is a mandatory field, but
    // it is optional for top level fields, and map/array "values" definitions.
    int32 index = 1 [(google.api.field_behavior) = OPTIONAL];

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

    // Required. The datatype of this field. The following values are supported:
    //
    // Primitive types:
    //
    // * string
    // * integer
    // * boolean
    // * double
    // * datetime. Must be of the format RFC3339 UTC "Zulu" (Examples:
    // "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z").
    //
    // Complex types:
    //
    // * enum
    // * array
    // * map
    // * record
    string type = 5 [(google.api.field_behavior) = REQUIRED];

    // Optional. Field definition. You must specify it if the type is record. It
    // defines the nested fields.
    repeated MetadataTemplate record_fields = 6
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The list of values for an enum type. You must define it if the
    // type is enum.
    repeated EnumValue enum_values = 8 [(google.api.field_behavior) = OPTIONAL];

    // Optional. If the type is map, set map_items. map_items can refer to a
    // primitive field or a complex (record only) field. To specify a primitive
    // field, you only need to set name and type in the nested
    // MetadataTemplate. The recommended value for the name field is item, as
    // this isn't used in the actual payload.
    MetadataTemplate map_items = 10 [(google.api.field_behavior) = OPTIONAL];

    // Optional. If the type is array, set array_items. array_items can refer
    // to a primitive field or a complex (record only) field. To specify a
    // primitive field, you only need to set name and type in the nested
    // MetadataTemplate. The recommended value for the name field is item, as
    // this isn't used in the actual payload.
    MetadataTemplate array_items = 11 [(google.api.field_behavior) = OPTIONAL];

    // Optional. You can use type id if this definition of the field needs to be
    // reused later. The type id must be unique across the entire template. You
    // can only specify it if the field type is record.
    string type_id = 12 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A reference to another field definition (not an inline
    // definition). The value must be equal to the value of an id field defined
    // elsewhere in the MetadataTemplate. Only fields with record type can
    // refer to other fields.
    string type_ref = 13 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specifies the constraints on this field.
    Constraints constraints = 50 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specifies annotations on this field.
    Annotations annotations = 51 [(google.api.field_behavior) = OPTIONAL];
  }

  // Output only. The relative resource name of the AspectType, of the form:
  // projects/{project_number}/locations/{location_id}/aspectTypes/{aspect_type_id}.
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/AspectType"
    }
  ];

  // Output only. System generated globally unique ID for the AspectType.
  // If you delete and recreate the AspectType with the same name, then this ID
  // will be different.
  string uid = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the AspectType was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the AspectType was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Description of the AspectType.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User friendly display name.
  string display_name = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined labels for the AspectType.
  map<string, string> labels = 7 [(google.api.field_behavior) = OPTIONAL];

  // The service computes this checksum. The client may send it on update and
  // delete requests to ensure it has an up-to-date value before proceeding.
  string etag = 8;

  // Immutable. Defines the Authorization for this type.
  Authorization authorization = 52 [(google.api.field_behavior) = IMMUTABLE];

  // Required. MetadataTemplate of the aspect.
  MetadataTemplate metadata_template = 53
      [(google.api.field_behavior) = REQUIRED];

  // Output only. Denotes the transfer status of the Aspect Type. It is
  // unspecified for Aspect Types created from Dataplex API.
  TransferStatus transfer_status = 202
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// An Entry Group represents a logical grouping of one or more Entries.
message EntryGroup {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/EntryGroup"
    pattern: "projects/{project}/locations/{location}/entryGroups/{entry_group}"
    plural: "entryGroups"
    singular: "entryGroup"
  };

  // Output only. The relative resource name of the EntryGroup, in the format
  // projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}.
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryGroup"
    }
  ];

  // Output only. System generated globally unique ID for the EntryGroup. If you
  // delete and recreate the EntryGroup with the same name, this ID will be
  // different.
  string uid = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the EntryGroup was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the EntryGroup was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Description of the EntryGroup.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User friendly display name.
  string display_name = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined labels for the EntryGroup.
  map<string, string> labels = 7 [(google.api.field_behavior) = OPTIONAL];

  // This checksum is computed by the service, and might be sent on update and
  // delete requests to ensure the client has an up-to-date value before
  // proceeding.
  string etag = 8;

  // Output only. Denotes the transfer status of the Entry Group. It is
  // unspecified for Entry Group created from Dataplex API.
  TransferStatus transfer_status = 202
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Entry Type is a template for creating Entries.
message EntryType {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/EntryType"
    pattern: "projects/{project}/locations/{location}/entryTypes/{entry_type}"
    plural: "entryTypes"
    singular: "entryType"
  };

  message AspectInfo {
    // Required aspect type for the entry type.
    string type = 1 [(google.api.resource_reference) = {
      type: "dataplex.googleapis.com/AspectType"
    }];
  }

  // Authorization for an Entry Type.
  message Authorization {
    // Immutable. The IAM permission grantable on the Entry Group to allow
    // access to instantiate Entries of Dataplex owned Entry Types, only
    // settable for Dataplex owned Types.
    string alternate_use_permission = 1
        [(google.api.field_behavior) = IMMUTABLE];
  }

  // Output only. The relative resource name of the EntryType, of the form:
  // projects/{project_number}/locations/{location_id}/entryTypes/{entry_type_id}.
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryType"
    }
  ];

  // Output only. System generated globally unique ID for the EntryType. This ID
  // will be different if the EntryType is deleted and re-created with the same
  // name.
  string uid = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the EntryType was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the EntryType was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Description of the EntryType.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User friendly display name.
  string display_name = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined labels for the EntryType.
  map<string, string> labels = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. This checksum is computed by the service, and might be sent on
  // update and delete requests to ensure the client has an up-to-date value
  // before proceeding.
  string etag = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Indicates the classes this Entry Type belongs to, for example,
  // TABLE, DATABASE, MODEL.
  repeated string type_aliases = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The platform that Entries of this type belongs to.
  string platform = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The system that Entries of this type belongs to. Examples include
  // CloudSQL, MariaDB etc
  string system = 11 [(google.api.field_behavior) = OPTIONAL];

  // AspectInfo for the entry type.
  repeated AspectInfo required_aspects = 50;

  // Immutable. Authorization defined for this type.
  Authorization authorization = 51 [(google.api.field_behavior) = IMMUTABLE];
}

// An aspect is a single piece of metadata describing an entry.
message Aspect {
  // Output only. The resource name of the type used to create this Aspect.
  string aspect_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The path in the entry under which the aspect is attached.
  string path = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the Aspect was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the Aspect was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The content of the aspect, according to its aspect type schema.
  // The maximum size of the field is 120KB (encoded as UTF-8).
  google.protobuf.Struct data = 8 [(google.api.field_behavior) = REQUIRED];

  // Optional. Information related to the source system of the aspect.
  AspectSource aspect_source = 9 [(google.api.field_behavior) = OPTIONAL];
}

// Information related to the source system of the aspect.
message AspectSource {
  // The time the aspect was created in the source system.
  google.protobuf.Timestamp create_time = 10;

  // The time the aspect was last updated in the source system.
  google.protobuf.Timestamp update_time = 11;

  // The version of the data format used to produce this data. This field is
  // used to indicated when the underlying data format changes (e.g., schema
  // modifications, changes to the source URL format definition, etc).
  string data_version = 12;
}

// An entry is a representation of a data resource that can be described by
// various metadata.
message Entry {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/Entry"
    pattern: "projects/{project}/locations/{location}/entryGroups/{entry_group}/entries/{entry}"
    plural: "entries"
    singular: "entry"
  };

  // Identifier. The relative resource name of the entry, in the format
  // `projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}/entries/{entry_id}`.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Required. Immutable. The relative resource name of the entry type that was
  // used to create this entry, in the format
  // `projects/{project_id_or_number}/locations/{location_id}/entryTypes/{entry_type_id}`.
  string entry_type = 4 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Output only. The time when the entry was created in Dataplex.
  google.protobuf.Timestamp create_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the entry was last updated in Dataplex.
  google.protobuf.Timestamp update_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The aspects that are attached to the entry. Depending on how the
  // aspect is attached to the entry, the format of the aspect key can be one of
  // the following:
  //
  // * If the aspect is attached directly to the entry:
  // `{project_id_or_number}.{location_id}.{aspect_type_id}`
  // * If the aspect is attached to an entry's path:
  // `{project_id_or_number}.{location_id}.{aspect_type_id}@{path}`
  map<string, Aspect> aspects = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Immutable. The resource name of the parent entry, in the format
  // `projects/{project_id_or_number}/locations/{location_id}/entryGroups/{entry_group_id}/entries/{entry_id}`.
  string parent_entry = 10 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. A name for the entry that can be referenced by an external
  // system. For more information, see [Fully qualified
  // names](https://cloud.google.com/data-catalog/docs/fully-qualified-names).
  // The maximum size of the field is 4000 characters.
  string fully_qualified_name = 12 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Information related to the source system of the data resource
  // that is represented by the entry.
  EntrySource entry_source = 15 [(google.api.field_behavior) = OPTIONAL];
}

// Information related to the source system of the data resource that is
// represented by the entry.
message EntrySource {
  // Information about individual items in the hierarchy that is associated with
  // the data resource.
  message Ancestor {
    // Optional. The name of the ancestor resource.
    string name = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The type of the ancestor resource.
    string type = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // The name of the resource in the source system.
  // Maximum length is 4,000 characters.
  string resource = 1;

  // The name of the source system.
  // Maximum length is 64 characters.
  string system = 2;

  // The platform containing the source system.
  // Maximum length is 64 characters.
  string platform = 3;

  // A user-friendly display name.
  // Maximum length is 500 characters.
  string display_name = 5;

  // A description of the data resource.
  // Maximum length is 2,000 characters.
  string description = 6;

  // User-defined labels.
  // The maximum size of keys and values is 128 characters each.
  map<string, string> labels = 7;

  // Immutable. The entries representing the ancestors of the data resource in
  // the source system.
  repeated Ancestor ancestors = 9 [(google.api.field_behavior) = IMMUTABLE];

  // The time when the resource was created in the source system.
  google.protobuf.Timestamp create_time = 10;

  // The time when the resource was last updated in the source system. If the
  // entry exists in the system and its `EntrySource` has `update_time`
  // populated, further updates to the `EntrySource` of the entry must provide
  // incremental updates to its `update_time`.
  google.protobuf.Timestamp update_time = 11;

  // Output only. Location of the resource in the source system. You can search
  // the entry by this location. By default, this should match the location of
  // the entry group containing this entry. A different value allows capturing
  // the source location for data external to Google Cloud.
  string location = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Create EntryGroup Request.
message CreateEntryGroupRequest {
  // Required. The resource name of the entryGroup, of the form:
  // projects/{project_number}/locations/{location_id}
  // where `location_id` refers to a GCP region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. EntryGroup identifier.
  string entry_group_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. EntryGroup Resource.
  EntryGroup entry_group = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. The service validates the request without performing any
  // mutations. The default is false.
  bool validate_only = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Update EntryGroup Request.
message UpdateEntryGroupRequest {
  // Required. EntryGroup Resource.
  EntryGroup entry_group = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Mask of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The service validates the request, without performing any
  // mutations. The default is false.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Delete EntryGroup Request.
message DeleteEntryGroupRequest {
  // Required. The resource name of the EntryGroup:
  // `projects/{project_number}/locations/{location_id}/entryGroups/{entry_group_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryGroup"
    }
  ];

  // Optional. If the client provided etag value does not match the current etag
  // value, the DeleteEntryGroupRequest method returns an ABORTED error
  // response.
  string etag = 2 [(google.api.field_behavior) = OPTIONAL];
}

// List entryGroups request.
message ListEntryGroupsRequest {
  // Required. The resource name of the entryGroup location, of the form:
  // `projects/{project_number}/locations/{location_id}`
  // where `location_id` refers to a Google Cloud region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Optional. Maximum number of EntryGroups to return. The service may return
  // fewer than this value. If unspecified, the service returns at most 10
  // EntryGroups. The maximum value is 1000; values above 1000 will be coerced
  // to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

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

  // Optional. Filter request.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

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

// List entry groups response.
message ListEntryGroupsResponse {
  // Entry groups under the given parent location.
  repeated EntryGroup entry_groups = 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;

  // Locations that the service couldn't reach.
  repeated string unreachable_locations = 3;
}

// Get EntryGroup request.
message GetEntryGroupRequest {
  // Required. The resource name of the EntryGroup:
  // `projects/{project_number}/locations/{location_id}/entryGroups/{entry_group_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryGroup"
    }
  ];
}

// Create EntryType Request.
message CreateEntryTypeRequest {
  // Required. The resource name of the EntryType, of the form:
  // projects/{project_number}/locations/{location_id}
  // where `location_id` refers to a Google Cloud region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. EntryType identifier.
  string entry_type_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. EntryType Resource.
  EntryType entry_type = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. The service validates the request without performing any
  // mutations. The default is false.
  bool validate_only = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Update EntryType Request.
message UpdateEntryTypeRequest {
  // Required. EntryType Resource.
  EntryType entry_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Mask of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The service validates the request without performing any
  // mutations. The default is false.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Delele EntryType Request.
message DeleteEntryTypeRequest {
  // Required. The resource name of the EntryType:
  // `projects/{project_number}/locations/{location_id}/entryTypes/{entry_type_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryType"
    }
  ];

  // Optional. If the client provided etag value does not match the current etag
  // value, the DeleteEntryTypeRequest method returns an ABORTED error response.
  string etag = 2 [(google.api.field_behavior) = OPTIONAL];
}

// List EntryTypes request
message ListEntryTypesRequest {
  // Required. The resource name of the EntryType location, of the form:
  // `projects/{project_number}/locations/{location_id}`
  // where `location_id` refers to a Google Cloud region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Optional. Maximum number of EntryTypes to return. The service may return
  // fewer than this value. If unspecified, the service returns at most 10
  // EntryTypes. The maximum value is 1000; values above 1000 will be coerced to
  // 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

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

  // Optional. Filter request. Filters are case-sensitive.
  // The service supports the following formats:
  //
  // * labels.key1 = "value1"
  // * labels:key1
  // * name = "value"
  //
  // These restrictions can be conjoined with AND, OR, and NOT conjunctions.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Orders the result by `name` or `create_time` fields.
  // If not specified, the ordering is undefined.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// List EntryTypes response.
message ListEntryTypesResponse {
  // EntryTypes under the given parent location.
  repeated EntryType entry_types = 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;

  // Locations that the service couldn't reach.
  repeated string unreachable_locations = 3;
}

// Get EntryType request.
message GetEntryTypeRequest {
  // Required. The resource name of the EntryType:
  // `projects/{project_number}/locations/{location_id}/entryTypes/{entry_type_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryType"
    }
  ];
}

// Create AspectType Request.
message CreateAspectTypeRequest {
  // Required. The resource name of the AspectType, of the form:
  // projects/{project_number}/locations/{location_id}
  // where `location_id` refers to a Google Cloud region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. AspectType identifier.
  string aspect_type_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. AspectType Resource.
  AspectType aspect_type = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. The service validates the request without performing any
  // mutations. The default is false.
  bool validate_only = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Update AspectType Request
message UpdateAspectTypeRequest {
  // Required. AspectType Resource
  AspectType aspect_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Mask of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Only validate the request, but do not perform mutations.
  // The default is false.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Delele AspectType Request.
message DeleteAspectTypeRequest {
  // Required. The resource name of the AspectType:
  // `projects/{project_number}/locations/{location_id}/aspectTypes/{aspect_type_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/AspectType"
    }
  ];

  // Optional. If the client provided etag value does not match the current etag
  // value, the DeleteAspectTypeRequest method returns an ABORTED error
  // response.
  string etag = 2 [(google.api.field_behavior) = OPTIONAL];
}

// List AspectTypes request.
message ListAspectTypesRequest {
  // Required. The resource name of the AspectType location, of the form:
  // `projects/{project_number}/locations/{location_id}`
  // where `location_id` refers to a Google Cloud region.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Optional. Maximum number of AspectTypes to return. The service may return
  // fewer than this value. If unspecified, the service returns at most 10
  // AspectTypes. The maximum value is 1000; values above 1000 will be coerced
  // to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

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

  // Optional. Filter request. Filters are case-sensitive.
  // The service supports the following formats:
  //
  // * labels.key1 = "value1"
  // * labels:key1
  // * name = "value"
  //
  // These restrictions can be conjoined with AND, OR, and NOT conjunctions.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Orders the result by `name` or `create_time` fields.
  // If not specified, the ordering is undefined.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// List AspectTypes response.
message ListAspectTypesResponse {
  // AspectTypes under the given parent location.
  repeated AspectType aspect_types = 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;

  // Locations that the service couldn't reach.
  repeated string unreachable_locations = 3;
}

// Get AspectType request.
message GetAspectTypeRequest {
  // Required. The resource name of the AspectType:
  // `projects/{project_number}/locations/{location_id}/aspectTypes/{aspect_type_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/AspectType"
    }
  ];
}

// Create Entry request.
message CreateEntryRequest {
  // Required. The resource name of the parent Entry Group:
  // `projects/{project}/locations/{location}/entryGroups/{entry_group}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryGroup"
    }
  ];

  // Required. Entry identifier. It has to be unique within an Entry Group.
  //
  // Entries corresponding to Google Cloud resources use an Entry ID format
  // based on [full resource
  // names](https://cloud.google.com/apis/design/resource_names#full_resource_name).
  // The format is a full resource name of the resource without the
  // prefix double slashes in the API service name part of the full resource
  // name. This allows retrieval of entries using their associated resource
  // name.
  //
  // For example, if the full resource name of a resource is
  // `//library.googleapis.com/shelves/shelf1/books/book2`,
  // then the suggested entry_id is
  // `library.googleapis.com/shelves/shelf1/books/book2`.
  //
  // It is also suggested to follow the same convention for entries
  // corresponding to resources from providers or systems other than Google
  // Cloud.
  //
  // The maximum size of the field is 4000 characters.
  string entry_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Entry resource.
  Entry entry = 3 [(google.api.field_behavior) = REQUIRED];
}

// Update Entry request.
message UpdateEntryRequest {
  // Required. Entry resource.
  Entry entry = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Mask of fields to update. To update Aspects, the update_mask must
  // contain the value "aspects".
  //
  // If the update_mask is empty, the service will update all modifiable fields
  // present in the request.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set to true and the entry doesn't exist, the service will
  // create it.
  bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set to true and the aspect_keys specify aspect ranges, the
  // service deletes any existing aspects from that range that weren't provided
  // in the request.
  bool delete_missing_aspects = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The map keys of the Aspects which the service should modify. It
  // supports the following syntaxes:
  //
  // * `<aspect_type_reference>` - matches an aspect of the given type and empty
  // path.
  // * `<aspect_type_reference>@path` - matches an aspect of the given type and
  // specified path. For example, to attach an aspect to a field that is
  // specified by the `schema` aspect, the path should have the format
  // `Schema.<field_name>`.
  // * `<aspect_type_reference>@*` - matches aspects of the given type for all
  // paths.
  // * `*@path` - matches aspects of all types on the given path.
  //
  // The service will not remove existing aspects matching the syntax unless
  // `delete_missing_aspects` is set to true.
  //
  // If this field is left empty, the service treats it as specifying
  // exactly those Aspects present in the request.
  repeated string aspect_keys = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Delete Entry request.
message DeleteEntryRequest {
  // Required. The resource name of the Entry:
  // `projects/{project}/locations/{location}/entryGroups/{entry_group}/entries/{entry}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dataplex.googleapis.com/Entry" }
  ];
}

// List Entries request.
message ListEntriesRequest {
  // Required. The resource name of the parent Entry Group:
  // `projects/{project}/locations/{location}/entryGroups/{entry_group}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/EntryGroup"
    }
  ];

  // Optional. Number of items to return per page. If there are remaining
  // results, the service returns a next_page_token. If unspecified, the service
  // returns at most 10 Entries. The maximum value is 100; values above 100 will
  // be coerced to 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Page token received from a previous `ListEntries` call. Provide
  // this to retrieve the subsequent page.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A filter on the entries to return. Filters are case-sensitive.
  // You can filter the request by the following fields:
  //
  // * entry_type
  // * entry_source.display_name
  //
  // The comparison operators are =, !=, <, >, <=, >=. The service compares
  // strings according to lexical order.
  //
  // You can use the logical operators AND, OR, NOT in the filter.
  //
  // You can use Wildcard "*", but for entry_type you need to provide the
  // full project id or number.
  //
  // Example filter expressions:
  //
  // * "entry_source.display_name=AnExampleDisplayName"
  // * "entry_type=projects/example-project/locations/global/entryTypes/example-entry_type"
  // * "entry_type=projects/example-project/locations/us/entryTypes/a* OR
  // entry_type=projects/another-project/locations/*"
  // * "NOT entry_source.display_name=AnotherExampleDisplayName"
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];
}

// List Entries response.
message ListEntriesResponse {
  // The list of entries under the given parent location.
  repeated Entry entries = 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;
}

// Get Entry request.
message GetEntryRequest {
  // Required. The resource name of the Entry:
  // `projects/{project}/locations/{location}/entryGroups/{entry_group}/entries/{entry}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dataplex.googleapis.com/Entry" }
  ];

  // Optional. View to control which parts of an entry the service should
  // return.
  EntryView view = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Limits the aspects returned to the provided aspect types.
  // It only works for CUSTOM view.
  repeated string aspect_types = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Limits the aspects returned to those associated with the provided
  // paths within the Entry. It only works for CUSTOM view.
  repeated string paths = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Lookup Entry request using permissions in the source system.
message LookupEntryRequest {
  // Required. The project to which the request should be attributed in the
  // following form: `projects/{project}/locations/{location}`.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. View to control which parts of an entry the service should
  // return.
  EntryView view = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Limits the aspects returned to the provided aspect types.
  // It only works for CUSTOM view.
  repeated string aspect_types = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Limits the aspects returned to those associated with the provided
  // paths within the Entry. It only works for CUSTOM view.
  repeated string paths = 4 [(google.api.field_behavior) = OPTIONAL];

  // Required. The resource name of the Entry:
  // `projects/{project}/locations/{location}/entryGroups/{entry_group}/entries/{entry}`.
  string entry = 5 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dataplex.googleapis.com/Entry" }
  ];
}

message SearchEntriesRequest {
  // Required. The project to which the request should be attributed in the
  // following form: `projects/{project}/locations/{location}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The query against which entries in scope should be matched.
  // The query syntax is defined in [Search syntax for Dataplex
  // Catalog](https://cloud.google.com/dataplex/docs/search-syntax).
  string query = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Number of results in the search page. If <=0, then defaults
  // to 10. Max limit for page_size is 1000. Throws an invalid argument for
  // page_size > 1000.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Page token received from a previous `SearchEntries` call. Provide
  // this to retrieve the subsequent page.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies the ordering of results.
  // Supported values are:
  //
  // * `relevance` (default)
  // * `last_modified_timestamp`
  // * `last_modified_timestamp asc`
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The scope under which the search should be operating. It must
  // either be `organizations/<org_id>` or `projects/<project_ref>`. If it is
  // unspecified, it defaults to the organization where the project provided in
  // `name` is located.
  string scope = 7 [(google.api.field_behavior) = OPTIONAL];
}

// A single result of a SearchEntries request.
message SearchEntriesResult {
  // Snippets for the entry, contains HTML-style highlighting for
  // matched tokens, will be used in UI.
  message Snippets {
    option deprecated = true;

    // Entry
    Entry dataplex_entry = 1 [deprecated = true];
  }

  // Linked resource name.
  string linked_resource = 8 [deprecated = true];

  Entry dataplex_entry = 9;

  // Snippets.
  Snippets snippets = 12 [deprecated = true];
}

message SearchEntriesResponse {
  // The results matching the search query.
  repeated SearchEntriesResult results = 1;

  // The estimated total number of matching entries. This number isn't
  // guaranteed to be accurate.
  int32 total_size = 2;

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

  // Locations that the service couldn't reach. Search results don't include
  // data from these locations.
  repeated string unreachable = 4;
}

// An object that describes the values that you want to set for an entry and its
// attached aspects when you import metadata. Used when you run a metadata
// import job. See
// [CreateMetadataJob][google.cloud.dataplex.v1.CatalogService.CreateMetadataJob].
//
// You provide a collection of import items in a metadata import file. For more
// information about how to create a metadata import file, see [Metadata import
// file](https://cloud.google.com/dataplex/docs/import-metadata#metadata-import-file).
message ImportItem {
  // Information about an entry and its attached aspects.
  Entry entry = 1;

  // The fields to update, in paths that are relative to the `Entry` resource.
  // Separate each field with a comma.
  //
  // In `FULL` entry sync mode, Dataplex includes the paths of all of the fields
  // for an entry that can be modified, including aspects. This means that
  // Dataplex replaces the existing entry with the entry in the metadata import
  // file. All modifiable fields are updated, regardless of the fields that are
  // listed in the update mask, and regardless of whether a field is present
  // in the `entry` object.
  //
  // The `update_mask` field is ignored when an entry is created or re-created.
  //
  // In an aspect-only metadata job (when entry sync mode is `NONE`), set this
  // value to `aspects`.
  //
  //
  // Dataplex also determines which entries and aspects to modify by comparing
  // the values and timestamps that you provide in the metadata import file with
  // the values and timestamps that exist in your project. For more information,
  // see [Comparison
  // logic](https://cloud.google.com/dataplex/docs/import-metadata#data-modification-logic).
  google.protobuf.FieldMask update_mask = 2;

  // The aspects to modify. Supports the following syntaxes:
  //
  // * `{aspect_type_reference}`: matches aspects that belong to the specified
  // aspect type and are attached directly to the entry.
  // * `{aspect_type_reference}@{path}`: matches aspects that belong to the
  // specified aspect type and path.
  // * `{aspect_type_reference}@*` : matches aspects of the given type for all
  // paths.
  // * `*@path` : matches aspects of all types on the given path.
  //
  // Replace `{aspect_type_reference}` with a reference to the aspect type, in
  // the format
  // `{project_id_or_number}.{location_id}.{aspect_type_id}`.
  //
  // In `FULL` entry sync mode, if you leave this field empty, it is treated as
  // specifying exactly those aspects that are present within the specified
  // entry. Dataplex implicitly adds the keys for all of the required aspects of
  // an entry.
  repeated string aspect_keys = 3;
}

// Create metadata job request.
message CreateMetadataJobRequest {
  // Required. The resource name of the parent location, in the format
  // `projects/{project_id_or_number}/locations/{location_id}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The metadata job resource.
  MetadataJob metadata_job = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The metadata job ID. If not provided, a unique ID is generated
  // with the prefix `metadata-job-`.
  string metadata_job_id = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The service validates the request without performing any
  // mutations. The default is false.
  bool validate_only = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Get metadata job request.
message GetMetadataJobRequest {
  // Required. The resource name of the metadata job, in the format
  // `projects/{project_id_or_number}/locations/{location_id}/metadataJobs/{metadata_job_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/MetadataJob"
    }
  ];
}

// List metadata jobs request.
message ListMetadataJobsRequest {
  // Required. The resource name of the parent location, in the format
  // `projects/{project_id_or_number}/locations/{location_id}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Optional. The maximum number of metadata jobs to return. The service might
  // return fewer jobs than this value. If unspecified, at most 10 jobs are
  // returned. The maximum value is 1,000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

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

  // Optional. Filter request. Filters are case-sensitive.
  // The service supports the following formats:
  //
  // * `labels.key1 = "value1"`
  // * `labels:key1`
  // * `name = "value"`
  //
  // You can combine filters with `AND`, `OR`, and `NOT` operators.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The field to sort the results by, either `name` or `create_time`.
  // If not specified, the ordering is undefined.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// List metadata jobs response.
message ListMetadataJobsResponse {
  // Metadata jobs under the specified parent location.
  repeated MetadataJob metadata_jobs = 1;

  // A token to retrieve the next page of results. If there are no more results
  // in the list, the value is empty.
  string next_page_token = 2;

  // Locations that the service couldn't reach.
  repeated string unreachable_locations = 3;
}

// Cancel metadata job request.
message CancelMetadataJobRequest {
  // Required. The resource name of the job, in the format
  // `projects/{project_id_or_number}/locations/{location_id}/metadataJobs/{metadata_job_id}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/MetadataJob"
    }
  ];
}

// A metadata job resource.
message MetadataJob {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/MetadataJob"
    pattern: "projects/{project}/locations/{location}/metadataJobs/{metadataJob}"
  };

  // Results from a metadata import job.
  message ImportJobResult {
    // Output only. The total number of entries that were deleted.
    int64 deleted_entries = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of entries that were updated.
    int64 updated_entries = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of entries that were created.
    int64 created_entries = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of entries that were unchanged.
    int64 unchanged_entries = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of entries that were recreated.
    int64 recreated_entries = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The time when the status was updated.
    google.protobuf.Timestamp update_time = 5
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Export Job Results. The result is based on the snapshot at the time when
  // the job is created.
  message ExportJobResult {
    // Output only. The number of entries that have been exported.
    int64 exported_entries = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The error message if the export job failed.
    string error_message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Job specification for a metadata import job.
  //
  // You can run the following kinds of metadata import jobs:
  //
  // * Full sync of entries with incremental import of their aspects.
  // Supported for custom entries.
  // * Incremental import of aspects only. Supported for aspects that belong
  // to custom entries and system entries. For custom entries, you can modify
  // both optional aspects and required aspects. For system entries, you can
  // modify optional aspects.
  message ImportJobSpec {
    // Specifies how the entries and aspects in a metadata job are updated. For
    // more information, see [Sync
    // mode](https://cloud.google.com/dataplex/docs/import-metadata#sync-mode).
    enum SyncMode {
      // Sync mode unspecified.
      SYNC_MODE_UNSPECIFIED = 0;

      // All resources in the job's scope are modified. If a resource exists in
      // Dataplex but isn't included in the metadata import file, the resource
      // is deleted when you run the metadata job. Use this mode to perform a
      // full sync of the set of entries in the job scope.
      //
      // This sync mode is supported for entries.
      FULL = 1;

      // Only the resources that are explicitly included in the
      // metadata import file are modified. Use this mode to modify a subset of
      // resources while leaving unreferenced resources unchanged.
      //
      // This sync mode is supported for aspects.
      INCREMENTAL = 2;

      // If entry sync mode is `NONE`, then aspects are modified according
      // to the aspect sync mode. Other metadata that belongs to entries in the
      // job's scope isn't modified.
      //
      // This sync mode is supported for entries.
      NONE = 3;
    }

    // The level of logs to write to Cloud Logging for this job.
    enum LogLevel {
      // Log level unspecified.
      LOG_LEVEL_UNSPECIFIED = 0;

      // Debug-level logging. Captures detailed logs for each import item. Use
      // debug-level logging to troubleshoot issues with specific import items.
      // For example, use debug-level logging to identify resources that are
      // missing from the job scope, entries or aspects that don't conform to
      // the associated entry type or aspect type, or other misconfigurations
      // with the metadata import file.
      //
      // Depending on the size of your metadata job and the number of logs that
      // are generated, debug-level logging might incur
      // [additional costs](https://cloud.google.com/stackdriver/pricing).
      DEBUG = 1;

      // Info-level logging. Captures logs at the overall job level. Includes
      // aggregate logs about import items, but doesn't specify which import
      // item has an error.
      INFO = 2;
    }

    // A boundary on the scope of impact that the metadata import job can have.
    message ImportJobScope {
      // Required. The entry group that is in scope for the import job,
      // specified as a relative resource name in the format
      // `projects/{project_number_or_id}/locations/{location_id}/entryGroups/{entry_group_id}`.
      // Only entries and aspects that belong to the specified entry group are
      // affected by the job.
      //
      // Must contain exactly one element. The entry group and the job
      // must be in the same location.
      repeated string entry_groups = 1 [
        (google.api.field_behavior) = REQUIRED,
        (google.api.resource_reference) = {
          type: "dataplex.googleapis.com/EntryGroup"
        }
      ];

      // Required. The entry types that are in scope for the import job,
      // specified as relative resource names in the format
      // `projects/{project_number_or_id}/locations/{location_id}/entryTypes/{entry_type_id}`.
      // The job modifies only the entries and aspects that belong to these
      // entry types.
      //
      // If the metadata import file attempts to modify an entry whose type
      // isn't included in this list, the import job is halted before modifying
      // any entries or aspects.
      //
      // The location of an entry type must either match the location of the
      // job, or the entry type must be global.
      repeated string entry_types = 2 [
        (google.api.field_behavior) = REQUIRED,
        (google.api.resource_reference) = {
          type: "dataplex.googleapis.com/EntryType"
        }
      ];

      // Optional. The aspect types that are in scope for the import job,
      // specified as relative resource names in the format
      // `projects/{project_number_or_id}/locations/{location_id}/aspectTypes/{aspect_type_id}`.
      // The job modifies only the aspects that belong to these aspect types.
      //
      // This field is required when creating an aspect-only import job.
      //
      // If the metadata import file attempts to modify an aspect whose type
      // isn't included in this list, the import job is halted before modifying
      // any entries or aspects.
      //
      // The location of an aspect type must either match the location of the
      // job, or the aspect type must be global.
      repeated string aspect_types = 3 [
        (google.api.field_behavior) = OPTIONAL,
        (google.api.resource_reference) = {
          type: "dataplex.googleapis.com/AspectType"
        }
      ];
    }

    // Optional. The URI of a Cloud Storage bucket or folder (beginning with
    // `gs://` and ending with `/`) that contains the metadata import files for
    // this job.
    //
    // A metadata import file defines the values to set for each of the entries
    // and aspects in a metadata job. For more information about how to create a
    // metadata import file and the file requirements, see [Metadata import
    // file](https://cloud.google.com/dataplex/docs/import-metadata#metadata-import-file).
    //
    // You can provide multiple metadata import files in the same metadata job.
    // The bucket or folder must contain at least one metadata import file, in
    // JSON Lines format (either `.json` or `.jsonl` file extension).
    //
    // In `FULL` entry sync mode, don't save the metadata import file in a
    // folder named `SOURCE_STORAGE_URI/deletions/`.
    //
    // **Caution**: If the metadata import file contains no data, all entries
    // and aspects that belong to the job's scope are deleted.
    string source_storage_uri = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The time when the process that created the metadata import
    // files began.
    google.protobuf.Timestamp source_create_time = 5
        [(google.api.field_behavior) = OPTIONAL];

    // Required. A boundary on the scope of impact that the metadata import job
    // can have.
    ImportJobScope scope = 2 [(google.api.field_behavior) = REQUIRED];

    // Required. The sync mode for entries.
    SyncMode entry_sync_mode = 3 [(google.api.field_behavior) = REQUIRED];

    // Required. The sync mode for aspects.
    SyncMode aspect_sync_mode = 4 [(google.api.field_behavior) = REQUIRED];

    // Optional. The level of logs to write to Cloud Logging for this job.
    //
    // Debug-level logs provide highly-detailed information for
    // troubleshooting, but their increased verbosity could incur [additional
    // costs](https://cloud.google.com/stackdriver/pricing) that might not be
    // merited for all jobs.
    //
    // If unspecified, defaults to `INFO`.
    LogLevel log_level = 6 [(google.api.field_behavior) = OPTIONAL];
  }

  // Export job specification.
  message ExportJobSpec {
    // Scope of the export job.
    message ExportJobScope {
      // Indicating if it is an organization level export job.
      // - When set to true, exports all entries from entry groups and projects
      // sharing the same organization id of the Metadata Job. Only projects and
      // entry groups in the VPC-SC perimeter will be exported. The projects and
      // entry groups are ignored.
      // - When set to false, one of the projects or entry groups must be
      // specified.
      // - Default to false.
      bool organization_level = 1;

      // The projects that are in the scope of the export job. Can either be
      // project numbers or project IDs. If specified, only the entries from the
      // specified projects will be exported. The projects must be in the same
      // organization and in the VPC-SC perimeter. Either projects or
      // entry_groups can be specified when organization_level_export is set to
      // false.
      // Must follow the format: "projects/<project_id_or_number>"
      repeated string projects = 2 [(google.api.resource_reference) = {
        type: "cloudresourcemanager.googleapis.com/Project"
      }];

      // The entry groups that are in scope for the export job. Optional. If
      // specified, only entries in the specified entry groups will be exported
      // by the job. Must be in the VPC-SC perimeter of the job. The location of
      // the entry groups must be the same as the job. Either projects or
      // entry_groups can be specified when organization_level_export is set to
      // false. Must follow the format:
      // "projects/<project_id_or_number>/locations/<location>/entryGroups/<entry_group_id>"
      repeated string entry_groups = 3 [(google.api.resource_reference) = {
        type: "dataplex.googleapis.com/EntryGroup"
      }];

      // If specified, only entries of the specified types will be
      // affected by the job.
      // Must follow the format:
      // "projects/<project_id_or_number>/locations/<location>/entryTypes/<entry_type_id>"
      repeated string entry_types = 4 [(google.api.resource_reference) = {
        type: "dataplex.googleapis.com/EntryType"
      }];

      // The aspect types that are in scope for the export job.
      // Optional. If specified, only aspects of the specified types will be
      // affected by the job.
      // Must follow the format:
      // "projects/<project_id_or_number>/locations/<location>/aspectTypes/<aspect_type_id>"
      repeated string aspect_types = 5 [(google.api.resource_reference) = {
        type: "dataplex.googleapis.com/AspectType"
      }];
    }

    // Required. Selects the entries to be exported by this job.
    ExportJobScope scope = 2 [(google.api.field_behavior) = REQUIRED];

    // Required. The root path of the exported metadata.
    // Must be in the format: "gs://<bucket_id>"
    // Or specify a customized prefix after the bucket:
    // "gs://<bucket_id>/<folder1>/<folder2>/.../".
    // The length limit of the customized prefix is 128 characters.
    // The bucket must be in the same VPC-SC perimeter with the job.
    string output_path = 3 [(google.api.field_behavior) = REQUIRED];
  }

  // Metadata job type.
  enum Type {
    // Unspecified.
    TYPE_UNSPECIFIED = 0;

    // Import job.
    IMPORT = 1;

    // Export job type.
    EXPORT = 2;
  }

  // Metadata job status.
  message Status {
    // State of a metadata job.
    enum State {
      // State unspecified.
      STATE_UNSPECIFIED = 0;

      // The job is queued.
      QUEUED = 1;

      // The job is running.
      RUNNING = 2;

      // The job is being canceled.
      CANCELING = 3;

      // The job is canceled.
      CANCELED = 4;

      // The job succeeded.
      SUCCEEDED = 5;

      // The job failed.
      FAILED = 6;

      // The job completed with some errors.
      SUCCEEDED_WITH_ERRORS = 7;
    }

    // Output only. State of the metadata job.
    State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Message relating to the progression of a metadata job.
    string message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Progress tracking.
    int32 completion_percent = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The time when the status was updated.
    google.protobuf.Timestamp update_time = 4
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Identifier. The name of the resource that the configuration is
  // applied to, in the format
  // `projects/{project_number}/locations/{location_id}/metadataJobs/{metadata_job_id}`.
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IDENTIFIER
  ];

  // Output only. A system-generated, globally unique ID for the metadata job.
  // If the metadata job is deleted and then re-created with the same name, this
  // ID is different.
  string uid = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Output only. The time when the metadata job was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the metadata job was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. User-defined labels.
  map<string, string> labels = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. Metadata job type.
  Type type = 6 [(google.api.field_behavior) = REQUIRED];

  oneof spec {
    // Import job specification.
    ImportJobSpec import_spec = 100;

    // Export job specification.
    ExportJobSpec export_spec = 101;
  }

  oneof result {
    // Output only. Import job result.
    ImportJobResult import_result = 200
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Export job result.
    ExportJobResult export_result = 201
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Metadata job status.
  Status status = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// View for controlling which parts of an entry are to be returned.
enum EntryView {
  // Unspecified EntryView. Defaults to FULL.
  ENTRY_VIEW_UNSPECIFIED = 0;

  // Returns entry only, without aspects.
  BASIC = 1;

  // Returns all required aspects as well as the keys of all non-required
  // aspects.
  FULL = 2;

  // Returns aspects matching custom fields in GetEntryRequest. If the number of
  // aspects exceeds 100, the first 100 will be returned.
  CUSTOM = 3;

  // Returns all aspects. If the number of aspects exceeds 100, the first
  // 100 will be returned.
  ALL = 4;
}

// Denotes the transfer status of a resource. It is unspecified for resources
// created from Dataplex API.
enum TransferStatus {
  // The default value. It is set for resources that were not subject for
  // migration from Data Catalog service.
  TRANSFER_STATUS_UNSPECIFIED = 0;

  // Indicates that a resource was migrated from Data Catalog service but it
  // hasn't been transferred yet. In particular the resource cannot be updated
  // from Dataplex API.
  TRANSFER_STATUS_MIGRATED = 1;

  // Indicates that a resource was transferred from Data Catalog service. The
  // resource can only be updated from Dataplex API.
  TRANSFER_STATUS_TRANSFERRED = 2;
}
