// Copyright 2021 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.aiplatform.v1beta1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/aiplatform/v1beta1/entity_type.proto";
import "google/cloud/aiplatform/v1beta1/feature.proto";
import "google/cloud/aiplatform/v1beta1/feature_monitoring_stats.proto";
import "google/cloud/aiplatform/v1beta1/feature_selector.proto";
import "google/cloud/aiplatform/v1beta1/featurestore.proto";
import "google/cloud/aiplatform/v1beta1/io.proto";
import "google/cloud/aiplatform/v1beta1/operation.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.AIPlatform.V1Beta1";
option go_package = "google.golang.org/genproto/googleapis/cloud/aiplatform/v1beta1;aiplatform";
option java_multiple_files = true;
option java_outer_classname = "FeaturestoreServiceProto";
option java_package = "com.google.cloud.aiplatform.v1beta1";
option php_namespace = "Google\\Cloud\\AIPlatform\\V1beta1";
option ruby_package = "Google::Cloud::AIPlatform::V1beta1";

// The service that handles CRUD and List for resources for Featurestore.
service FeaturestoreService {
  option (google.api.default_host) = "aiplatform.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";

  // Creates a new Featurestore in a given project and location.
  rpc CreateFeaturestore(CreateFeaturestoreRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/locations/*}/featurestores"
      body: "featurestore"
    };
    option (google.api.method_signature) = "parent,featurestore";
    option (google.longrunning.operation_info) = {
      response_type: "Featurestore"
      metadata_type: "CreateFeaturestoreOperationMetadata"
    };
  }

  // Gets details of a single Featurestore.
  rpc GetFeaturestore(GetFeaturestoreRequest) returns (Featurestore) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/locations/*/featurestores/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists Featurestores in a given project and location.
  rpc ListFeaturestores(ListFeaturestoresRequest) returns (ListFeaturestoresResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*/locations/*}/featurestores"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates the parameters of a single Featurestore.
  rpc UpdateFeaturestore(UpdateFeaturestoreRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1beta1/{featurestore.name=projects/*/locations/*/featurestores/*}"
      body: "featurestore"
    };
    option (google.api.method_signature) = "featurestore,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Featurestore"
      metadata_type: "UpdateFeaturestoreOperationMetadata"
    };
  }

  // Deletes a single Featurestore. The Featurestore must not contain any
  // EntityTypes or `force` must be set to true for the request to succeed.
  rpc DeleteFeaturestore(DeleteFeaturestoreRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/locations/*/featurestores/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "DeleteOperationMetadata"
    };
  }

  // Creates a new EntityType in a given Featurestore.
  rpc CreateEntityType(CreateEntityTypeRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/locations/*/featurestores/*}/entityTypes"
      body: "entity_type"
    };
    option (google.api.method_signature) = "parent,entity_type";
    option (google.longrunning.operation_info) = {
      response_type: "EntityType"
      metadata_type: "CreateEntityTypeOperationMetadata"
    };
  }

  // Gets details of a single EntityType.
  rpc GetEntityType(GetEntityTypeRequest) returns (EntityType) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/locations/*/featurestores/*/entityTypes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists EntityTypes in a given Featurestore.
  rpc ListEntityTypes(ListEntityTypesRequest) returns (ListEntityTypesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*/locations/*/featurestores/*}/entityTypes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates the parameters of a single EntityType.
  rpc UpdateEntityType(UpdateEntityTypeRequest) returns (EntityType) {
    option (google.api.http) = {
      patch: "/v1beta1/{entity_type.name=projects/*/locations/*/featurestores/*/entityTypes/*}"
      body: "entity_type"
    };
    option (google.api.method_signature) = "entity_type,update_mask";
  }

  // Deletes a single EntityType. The EntityType must not have any Features
  // or `force` must be set to true for the request to succeed.
  rpc DeleteEntityType(DeleteEntityTypeRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/locations/*/featurestores/*/entityTypes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "DeleteOperationMetadata"
    };
  }

  // Creates a new Feature in a given EntityType.
  rpc CreateFeature(CreateFeatureRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features"
      body: "feature"
    };
    option (google.api.method_signature) = "parent,feature";
    option (google.longrunning.operation_info) = {
      response_type: "Feature"
      metadata_type: "CreateFeatureOperationMetadata"
    };
  }

  // Creates a batch of Features in a given EntityType.
  rpc BatchCreateFeatures(BatchCreateFeaturesRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features:batchCreate"
      body: "*"
    };
    option (google.api.method_signature) = "parent,requests";
    option (google.longrunning.operation_info) = {
      response_type: "BatchCreateFeaturesResponse"
      metadata_type: "BatchCreateFeaturesOperationMetadata"
    };
  }

  // Gets details of a single Feature.
  rpc GetFeature(GetFeatureRequest) returns (Feature) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists Features in a given EntityType.
  rpc ListFeatures(ListFeaturesRequest) returns (ListFeaturesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates the parameters of a single Feature.
  rpc UpdateFeature(UpdateFeatureRequest) returns (Feature) {
    option (google.api.http) = {
      patch: "/v1beta1/{feature.name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}"
      body: "feature"
    };
    option (google.api.method_signature) = "feature,update_mask";
  }

  // Deletes a single Feature.
  rpc DeleteFeature(DeleteFeatureRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "DeleteOperationMetadata"
    };
  }

  // Imports Feature values into the Featurestore from a source storage.
  //
  // The progress of the import is tracked by the returned operation. The
  // imported features are guaranteed to be visible to subsequent read
  // operations after the operation is marked as successfully done.
  //
  // If an import operation fails, the Feature values returned from
  // reads and exports may be inconsistent. If consistency is
  // required, the caller must retry the same import request again and wait till
  // the new operation returned is marked as successfully done.
  //
  // There are also scenarios where the caller can cause inconsistency.
  //
  //  - Source data for import contains multiple distinct Feature values for
  //    the same entity ID and timestamp.
  //  - Source is modified during an import. This includes adding, updating, or
  //  removing source data and/or metadata. Examples of updating metadata
  //  include but are not limited to changing storage location, storage class,
  //  or retention policy.
  //  - Online serving cluster is under-provisioned.
  rpc ImportFeatureValues(ImportFeatureValuesRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{entity_type=projects/*/locations/*/featurestores/*/entityTypes/*}:importFeatureValues"
      body: "*"
    };
    option (google.api.method_signature) = "entity_type";
    option (google.longrunning.operation_info) = {
      response_type: "ImportFeatureValuesResponse"
      metadata_type: "ImportFeatureValuesOperationMetadata"
    };
  }

  // Batch reads Feature values from a Featurestore.
  //
  // This API enables batch reading Feature values, where each read
  // instance in the batch may read Feature values of entities from one or
  // more EntityTypes. Point-in-time correctness is guaranteed for Feature
  // values of each read instance as of each instance's read timestamp.
  rpc BatchReadFeatureValues(BatchReadFeatureValuesRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{featurestore=projects/*/locations/*/featurestores/*}:batchReadFeatureValues"
      body: "*"
    };
    option (google.api.method_signature) = "featurestore";
    option (google.longrunning.operation_info) = {
      response_type: "BatchReadFeatureValuesResponse"
      metadata_type: "BatchReadFeatureValuesOperationMetadata"
    };
  }

  // Exports Feature values from all the entities of a target EntityType.
  rpc ExportFeatureValues(ExportFeatureValuesRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{entity_type=projects/*/locations/*/featurestores/*/entityTypes/*}:exportFeatureValues"
      body: "*"
    };
    option (google.api.method_signature) = "entity_type";
    option (google.longrunning.operation_info) = {
      response_type: "ExportFeatureValuesResponse"
      metadata_type: "ExportFeatureValuesOperationMetadata"
    };
  }

  // Searches Features matching a query in a given project.
  rpc SearchFeatures(SearchFeaturesRequest) returns (SearchFeaturesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{location=projects/*/locations/*}/featurestores:searchFeatures"
    };
    option (google.api.method_signature) = "location";
  }
}

// Request message for [FeaturestoreService.CreateFeaturestore][google.cloud.aiplatform.v1beta1.FeaturestoreService.CreateFeaturestore].
message CreateFeaturestoreRequest {
  // Required. The resource name of the Location to create Featurestores.
  // Format:
  // `projects/{project}/locations/{location}'`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "aiplatform.googleapis.com/Featurestore"
    }
  ];

  // Required. The Featurestore to create.
  Featurestore featurestore = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The ID to use for this Featurestore, which will become the final component
  // of the Featurestore's resource name.
  //
  // This value may be up to 60 characters, and valid characters are
  // `[a-z0-9_]`. The first character cannot be a number.
  //
  // The value must be unique within the project and location.
  string featurestore_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for [FeaturestoreService.GetFeaturestore][google.cloud.aiplatform.v1beta1.FeaturestoreService.GetFeaturestore].
message GetFeaturestoreRequest {
  // Required. The name of the Featurestore resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Featurestore"
    }
  ];
}

// Request message for [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeaturestores].
message ListFeaturestoresRequest {
  // Required. The resource name of the Location to list Featurestores.
  // Format:
  // `projects/{project}/locations/{location}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "aiplatform.googleapis.com/Featurestore"
    }
  ];

  // Lists the featurestores that match the filter expression. The following
  // fields are supported:
  //
  // * `create_time`: Supports =, !=, <, >, <=, and >= comparisons. Values must
  // be
  //   in RFC 3339 format.
  // * `update_time`: Supports =, !=, <, >, <=, and >= comparisons. Values must
  // be
  //   in RFC 3339 format.
  // * `online_serving_config.fixed_node_count`: Supports =, !=, <, >, <=,
  // and >= comparisons.
  // * `labels`: Supports key-value equality and key presence.
  //
  // Examples:
  //
  // * `create_time > "2020-01-01" OR update_time > "2020-01-01"`
  //    Featurestores created or updated after 2020-01-01.
  // * `labels.env = "prod"`
  //    Featurestores with label "env" set to "prod".
  string filter = 2;

  // The maximum number of Featurestores to return. The service may return fewer
  // than this value. If unspecified, at most 100 Featurestores will be
  // returned. The maximum value is 100; any value greater than 100 will be
  // coerced to 100.
  int32 page_size = 3;

  // A page token, received from a previous
  // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeaturestores] call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeaturestores] must
  // match the call that provided the page token.
  string page_token = 4;

  // A comma-separated list of fields to order by, sorted in ascending order.
  // Use "desc" after a field name for descending.
  // Supported Fields:
  //
  //   * `create_time`
  //   * `update_time`
  //   * `online_serving_config.fixed_node_count`
  string order_by = 5;

  // Mask specifying which fields to read.
  google.protobuf.FieldMask read_mask = 6;
}

// Response message for [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeaturestores].
message ListFeaturestoresResponse {
  // The Featurestores matching the request.
  repeated Featurestore featurestores = 1;

  // A token, which can be sent as [ListFeaturestoresRequest.page_token][google.cloud.aiplatform.v1beta1.ListFeaturestoresRequest.page_token] to
  // retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for [FeaturestoreService.UpdateFeaturestore][google.cloud.aiplatform.v1beta1.FeaturestoreService.UpdateFeaturestore].
message UpdateFeaturestoreRequest {
  // Required. The Featurestore's `name` field is used to identify the Featurestore to be
  // updated.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}`
  Featurestore featurestore = 1 [(google.api.field_behavior) = REQUIRED];

  // Field mask is used to specify the fields to be overwritten in the
  // Featurestore resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then only the non-empty fields present in the
  // request will be overwritten. Set the update_mask to `*` to override all
  // fields.
  //
  // Updatable fields:
  //
  //   * `labels`
  //   * `online_serving_config.fixed_node_count`
  google.protobuf.FieldMask update_mask = 2;
}

// Request message for [FeaturestoreService.DeleteFeaturestore][google.cloud.aiplatform.v1beta1.FeaturestoreService.DeleteFeaturestore].
message DeleteFeaturestoreRequest {
  // Required. The name of the Featurestore to be deleted.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Featurestore"
    }
  ];

  // If set to true, any EntityTypes and Features for this Featurestore will
  // also be deleted. (Otherwise, the request will only work if the Featurestore
  // has no EntityTypes.)
  bool force = 2;
}

// Request message for [FeaturestoreService.ImportFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.ImportFeatureValues].
message ImportFeatureValuesRequest {
  // Defines the Feature value(s) to import.
  message FeatureSpec {
    // Required. ID of the Feature to import values of. This Feature must exist in the
    // target EntityType, or the request will fail.
    string id = 1 [(google.api.field_behavior) = REQUIRED];

    // Source column to get the Feature values from. If not set, uses the column
    // with the same name as the Feature ID.
    string source_field = 2;
  }

  // Details about the source data, including the location of the storage and
  // the format.
  oneof source {
    AvroSource avro_source = 2;

    BigQuerySource bigquery_source = 3;

    CsvSource csv_source = 4;
  }

  // Source of Feature timestamp for all Feature values of each entity.
  // Timestamps must be millisecond-aligned.
  oneof feature_time_source {
    // Source column that holds the Feature timestamp for all Feature
    // values in each entity.
    string feature_time_field = 6;

    // Single Feature timestamp for all entities being imported. The
    // timestamp must not have higher than millisecond precision.
    google.protobuf.Timestamp feature_time = 7;
  }

  // Required. The resource name of the EntityType grouping the Features for which values
  // are being imported. Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entityType}`
  string entity_type = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // Source column that holds entity IDs. If not provided, entity IDs are
  // extracted from the column named `entity_id`.
  string entity_id_field = 5;

  // Required. Specifications defining which Feature values to import from the entity. The
  // request fails if no feature_specs are provided, and having multiple
  // feature_specs for one Feature is not allowed.
  repeated FeatureSpec feature_specs = 8 [(google.api.field_behavior) = REQUIRED];

  // If set, data will not be imported for online serving. This
  // is typically used for backfilling, where Feature generation timestamps are
  // not in the timestamp range needed for online serving.
  bool disable_online_serving = 9;

  // Specifies the number of workers that are used to write data to the
  // Featurestore. Consider the online serving capacity that you require to
  // achieve the desired import throughput without interfering with online
  // serving. The value must be positive, and less than or equal to 100.
  // If not set, defaults to using 1 worker. The low count ensures minimal
  // impact on online serving performance.
  int32 worker_count = 11;
}

// Response message for [FeaturestoreService.ImportFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.ImportFeatureValues].
message ImportFeatureValuesResponse {
  // Number of entities that have been imported by the operation.
  int64 imported_entity_count = 1;

  // Number of Feature values that have been imported by the operation.
  int64 imported_feature_value_count = 2;

  // The number of rows in input source that weren't imported due to either
  // * Not having any featureValues.
  // * Having a null entityId.
  // * Having a null timestamp.
  // * Not being parsable (applicable for CSV sources).
  int64 invalid_row_count = 6;
}

// Request message for [FeaturestoreService.BatchReadFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.BatchReadFeatureValues].
// (- Next Id: 6 -)
message BatchReadFeatureValuesRequest {
  // Describe pass-through fields in read_instance source.
  message PassThroughField {
    // Required. The name of the field in the CSV header or the name of the column in
    // BigQuery table. The naming restriction is the same as [Feature.name][google.cloud.aiplatform.v1beta1.Feature.name].
    string field_name = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // Selects Features of an EntityType to read values of and specifies read
  // settings.
  message EntityTypeSpec {
    // Required. ID of the EntityType to select Features. The EntityType id is the
    // [entity_type_id][google.cloud.aiplatform.v1beta1.CreateEntityTypeRequest.entity_type_id] specified
    // during EntityType creation.
    string entity_type_id = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. Selectors choosing which Feature values to read from the EntityType.
    FeatureSelector feature_selector = 2 [(google.api.field_behavior) = REQUIRED];

    // Per-Feature settings for the batch read.
    repeated DestinationFeatureSetting settings = 3;
  }

  oneof read_option {
    // Each read instance consists of exactly one read timestamp and one or more
    // entity IDs identifying entities of the corresponding EntityTypes whose
    // Features are requested.
    //
    // Each output instance contains Feature values of requested entities
    // concatenated together as of the read time.
    //
    // An example read instance may be `foo_entity_id, bar_entity_id,
    // 2020-01-01T10:00:00.123Z`.
    //
    // An example output instance may be `foo_entity_id, bar_entity_id,
    // 2020-01-01T10:00:00.123Z, foo_entity_feature1_value,
    // bar_entity_feature2_value`.
    //
    // Timestamp in each read instance must be millisecond-aligned.
    //
    // `csv_read_instances` are read instances stored in a plain-text CSV file.
    // The header should be:
    //     [ENTITY_TYPE_ID1], [ENTITY_TYPE_ID2], ..., timestamp
    //
    // The columns can be in any order.
    //
    // Values in the timestamp column must use the RFC 3339 format, e.g.
    // `2012-07-30T10:43:17.123Z`.
    CsvSource csv_read_instances = 3;

    // Similar to csv_read_instances, but from BigQuery source.
    BigQuerySource bigquery_read_instances = 5;
  }

  // Required. The resource name of the Featurestore from which to query Feature values.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}`
  string featurestore = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Featurestore"
    }
  ];

  // Required. Specifies output location and format.
  FeatureValueDestination destination = 4 [(google.api.field_behavior) = REQUIRED];

  // When not empty, the specified fields in the *_read_instances source will be
  // joined as-is in the output, in addition to those fields from the
  // Featurestore Entity.
  //
  // For BigQuery source, the type of the pass-through values will be
  // automatically inferred. For CSV source, the pass-through values will be
  // passed as opaque bytes.
  repeated PassThroughField pass_through_fields = 8;

  // Required. Specifies EntityType grouping Features to read values of and settings.
  // Each EntityType referenced in
  // [BatchReadFeatureValuesRequest.entity_type_specs] must have a column
  // specifying entity IDs in the EntityType in
  // [BatchReadFeatureValuesRequest.request][] .
  repeated EntityTypeSpec entity_type_specs = 7 [(google.api.field_behavior) = REQUIRED];
}

// Request message for [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.ExportFeatureValues].
message ExportFeatureValuesRequest {
  // Describes exporting Feature values as of the snapshot timestamp.
  message SnapshotExport {
    // Exports Feature values as of this timestamp. If not set,
    // retrieve values as of now. Timestamp, if present, must not have higher
    // than millisecond precision.
    google.protobuf.Timestamp snapshot_time = 1;
  }

  oneof mode {
    // Exports Feature values of all entities of the EntityType as of a snapshot
    // time.
    SnapshotExport snapshot_export = 3;
  }

  // Required. The resource name of the EntityType from which to export Feature values.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string entity_type = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // Required. Specifies destination location and format.
  FeatureValueDestination destination = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. Selects Features to export values of.
  FeatureSelector feature_selector = 5 [(google.api.field_behavior) = REQUIRED];

  // Per-Feature export settings.
  repeated DestinationFeatureSetting settings = 6;
}

message DestinationFeatureSetting {
  // Required. The ID of the Feature to apply the setting to.
  string feature_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Specify the field name in the export destination. If not specified,
  // Feature ID is used.
  string destination_field = 2;
}

// A destination location for Feature values and format.
message FeatureValueDestination {
  oneof destination {
    // Output in BigQuery format.
    // [BigQueryDestination.output_uri][google.cloud.aiplatform.v1beta1.BigQueryDestination.output_uri] in
    // [FeatureValueDestination.bigquery_destination][google.cloud.aiplatform.v1beta1.FeatureValueDestination.bigquery_destination] must refer to a table.
    BigQueryDestination bigquery_destination = 1;

    // Output in TFRecord format.
    //
    // Below are the mapping from Feature value type
    // in Featurestore to Feature value type in TFRecord:
    //
    //     Value type in Featurestore                 | Value type in TFRecord
    //     DOUBLE, DOUBLE_ARRAY                       | FLOAT_LIST
    //     INT64, INT64_ARRAY                         | INT64_LIST
    //     STRING, STRING_ARRAY, BYTES                | BYTES_LIST
    //     true -> byte_string("true"), false -> byte_string("false")
    //     BOOL, BOOL_ARRAY (true, false)             | BYTES_LIST
    TFRecordDestination tfrecord_destination = 2;

    // Output in CSV format. Array Feature value types are not allowed in CSV
    // format.
    CsvDestination csv_destination = 3;
  }
}

// Response message for [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.ExportFeatureValues].
message ExportFeatureValuesResponse {

}

// Response message for [FeaturestoreService.BatchReadFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.BatchReadFeatureValues].
message BatchReadFeatureValuesResponse {

}

// Request message for [FeaturestoreService.CreateEntityType][google.cloud.aiplatform.v1beta1.FeaturestoreService.CreateEntityType].
message CreateEntityTypeRequest {
  // Required. The resource name of the Featurestore to create EntityTypes.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Featurestore"
    }
  ];

  // The EntityType to create.
  EntityType entity_type = 2;

  // Required. The ID to use for the EntityType, which will become the final component of
  // the EntityType's resource name.
  //
  // This value may be up to 60 characters, and valid characters are
  // `[a-z0-9_]`. The first character cannot be a number.
  //
  // The value must be unique within a featurestore.
  string entity_type_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for [FeaturestoreService.GetEntityType][google.cloud.aiplatform.v1beta1.FeaturestoreService.GetEntityType].
message GetEntityTypeRequest {
  // Required. The name of the EntityType resource.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];
}

// Request message for [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListEntityTypes].
message ListEntityTypesRequest {
  // Required. The resource name of the Featurestore to list EntityTypes.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // Lists the EntityTypes that match the filter expression. The following
  // filters are supported:
  //
  // * `create_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must
  // be in RFC 3339 format.
  // * `update_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must
  // be in RFC 3339 format.
  // * `labels`: Supports key-value equality as well as key presence.
  //
  // Examples:
  //
  // * `create_time > \"2020-01-31T15:30:00.000000Z\" OR
  //      update_time > \"2020-01-31T15:30:00.000000Z\"` --> EntityTypes created
  //      or updated after 2020-01-31T15:30:00.000000Z.
  // * `labels.active = yes AND labels.env = prod` --> EntityTypes having both
  //     (active: yes) and (env: prod) labels.
  // * `labels.env: *` --> Any EntityType which has a label with 'env' as the
  //   key.
  string filter = 2;

  // The maximum number of EntityTypes to return. The service may return fewer
  // than this value. If unspecified, at most 1000 EntityTypes will be returned.
  // The maximum value is 1000; any value greater than 1000 will be coerced to
  // 1000.
  int32 page_size = 3;

  // A page token, received from a previous
  // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListEntityTypes] call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListEntityTypes] must
  // match the call that provided the page token.
  string page_token = 4;

  // A comma-separated list of fields to order by, sorted in ascending order.
  // Use "desc" after a field name for descending.
  //
  // Supported fields:
  //
  //   * `entity_type_id`
  //   * `create_time`
  //   * `update_time`
  string order_by = 5;

  // Mask specifying which fields to read.
  google.protobuf.FieldMask read_mask = 6;
}

// Response message for [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListEntityTypes].
message ListEntityTypesResponse {
  // The EntityTypes matching the request.
  repeated EntityType entity_types = 1;

  // A token, which can be sent as [ListEntityTypesRequest.page_token][google.cloud.aiplatform.v1beta1.ListEntityTypesRequest.page_token] to
  // retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for [FeaturestoreService.UpdateEntityType][google.cloud.aiplatform.v1beta1.FeaturestoreService.UpdateEntityType].
message UpdateEntityTypeRequest {
  // Required. The EntityType's `name` field is used to identify the EntityType to be
  // updated.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  EntityType entity_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Field mask is used to specify the fields to be overwritten in the
  // EntityType resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then only the non-empty fields present in the
  // request will be overwritten. Set the update_mask to `*` to override all
  // fields.
  //
  // Updatable fields:
  //
  //   * `description`
  //   * `labels`
  //   * `monitoring_config.snapshot_analysis.disabled`
  //   * `monitoring_config.snapshot_analysis.monitoring_interval`
  google.protobuf.FieldMask update_mask = 2;
}

// Request message for [FeaturestoreService.DeleteEntityTypes][].
message DeleteEntityTypeRequest {
  // Required. The name of the EntityType to be deleted.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // If set to true, any Features for this EntityType will also be deleted.
  // (Otherwise, the request will only work if the EntityType has no Features.)
  bool force = 2;
}

// Request message for [FeaturestoreService.CreateFeature][google.cloud.aiplatform.v1beta1.FeaturestoreService.CreateFeature].
message CreateFeatureRequest {
  // Required. The resource name of the EntityType to create a Feature.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // Required. The Feature to create.
  Feature feature = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The ID to use for the Feature, which will become the final component of
  // the Feature's resource name.
  //
  // This value may be up to 60 characters, and valid characters are
  // `[a-z0-9_]`. The first character cannot be a number.
  //
  // The value must be unique within an EntityType.
  string feature_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for [FeaturestoreService.BatchCreateFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.BatchCreateFeatures].
message BatchCreateFeaturesRequest {
  // Required. The resource name of the EntityType to create the batch of Features under.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/EntityType"
    }
  ];

  // Required. The request message specifying the Features to create. All Features must be
  // created under the same parent EntityType. The `parent` field in each child
  // request message can be omitted. If `parent` is set in a child request, then
  // the value must match the `parent` value in this request message.
  repeated CreateFeatureRequest requests = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response message for [FeaturestoreService.BatchCreateFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.BatchCreateFeatures].
message BatchCreateFeaturesResponse {
  // The Features created.
  repeated Feature features = 1;
}

// Request message for [FeaturestoreService.GetFeature][google.cloud.aiplatform.v1beta1.FeaturestoreService.GetFeature].
message GetFeatureRequest {
  // Required. The name of the Feature resource.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Feature"
    }
  ];
}

// Request message for [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeatures].
message ListFeaturesRequest {
  // Required. The resource name of the Location to list Features.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "aiplatform.googleapis.com/Feature"
    }
  ];

  // Lists the Features that match the filter expression. The following
  // filters are supported:
  //
  // * `value_type`: Supports = and != comparisons.
  // * `create_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must
  // be in RFC 3339 format.
  // * `update_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must
  // be in RFC 3339 format.
  // * `labels`: Supports key-value equality as well as key presence.
  //
  // Examples:
  //
  // * `value_type = DOUBLE` --> Features whose type is DOUBLE.
  // * `create_time > \"2020-01-31T15:30:00.000000Z\" OR
  //      update_time > \"2020-01-31T15:30:00.000000Z\"` --> EntityTypes created
  //      or updated after 2020-01-31T15:30:00.000000Z.
  // * `labels.active = yes AND labels.env = prod` --> Features having both
  //     (active: yes) and (env: prod) labels.
  // * `labels.env: *` --> Any Feature which has a label with 'env' as the
  //   key.
  string filter = 2;

  // The maximum number of Features to return. The service may return fewer
  // than this value. If unspecified, at most 1000 Features will be returned.
  // The maximum value is 1000; any value greater than 1000 will be coerced to
  // 1000.
  int32 page_size = 3;

  // A page token, received from a previous
  // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeatures] call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeatures] must
  // match the call that provided the page token.
  string page_token = 4;

  // A comma-separated list of fields to order by, sorted in ascending order.
  // Use "desc" after a field name for descending.
  // Supported fields:
  //
  //   * `feature_id`
  //   * `value_type`
  //   * `create_time`
  //   * `update_time`
  string order_by = 5;

  // Mask specifying which fields to read.
  google.protobuf.FieldMask read_mask = 6;

  // If set, return the most recent [ListFeaturesRequest.latest_stats_count][google.cloud.aiplatform.v1beta1.ListFeaturesRequest.latest_stats_count]
  // of stats for each Feature in response. Valid value is [0, 10]. If number of
  // stats exists < [ListFeaturesRequest.latest_stats_count][google.cloud.aiplatform.v1beta1.ListFeaturesRequest.latest_stats_count], return all
  // existing stats.
  int32 latest_stats_count = 7;
}

// Response message for [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeatures].
message ListFeaturesResponse {
  // The Features matching the request.
  repeated Feature features = 1;

  // A token, which can be sent as [ListFeaturesRequest.page_token][google.cloud.aiplatform.v1beta1.ListFeaturesRequest.page_token] to
  // retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.SearchFeatures].
message SearchFeaturesRequest {
  // Required. The resource name of the Location to search Features.
  // Format:
  // `projects/{project}/locations/{location}`
  string location = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Query string that is a conjunction of field-restricted queries and/or
  // field-restricted filters.  Field-restricted queries and filters can be
  // combined using `AND` to form a conjunction.
  //
  // A field query is in the form FIELD:QUERY. This implicitly checks if QUERY
  // exists as a substring within Feature's FIELD. The QUERY
  // and the FIELD are converted to a sequence of words (i.e. tokens) for
  // comparison. This is done by:
  //
  //   * Removing leading/trailing whitespace and tokenizing the search value.
  //   Characters that are not one of alphanumeric [a-zA-Z0-9], underscore [_],
  //   or asterisk [*] are treated as delimiters for tokens. (*) is treated as a
  //   wildcard that matches characters within a token.
  //   * Ignoring case.
  //   * Prepending an asterisk to the first and appending an asterisk to the
  //   last token in QUERY.
  //
  // A QUERY must be either a singular token or a phrase. A phrase is one or
  // multiple words enclosed in double quotation marks ("). With phrases, the
  // order of the words is important. Words in the phrase must be matching in
  // order and consecutively.
  //
  // Supported FIELDs for field-restricted queries:
  //
  // * `feature_id`
  // * `description`
  // * `entity_type_id`
  //
  // Examples:
  //
  // * `feature_id: foo` --> Matches a Feature with ID containing the substring
  // `foo` (eg. `foo`, `foofeature`, `barfoo`).
  // * `feature_id: foo*feature` --> Matches a Feature with ID containing the
  // substring `foo*feature` (eg. `foobarfeature`).
  // * `feature_id: foo AND description: bar` --> Matches a Feature with ID
  // containing the substring `foo` and description containing the substring
  // `bar`.
  //
  //
  // Besides field queries, the following exact-match filters are
  // supported. The exact-match filters do not support wildcards. Unlike
  // field-restricted queries, exact-match filters are case-sensitive.
  //
  // * `feature_id`: Supports = comparisons.
  // * `description`: Supports = comparisons. Multi-token filters should be
  // enclosed in quotes.
  // * `entity_type_id`: Supports = comparisons.
  // * `value_type`: Supports = and != comparisons.
  // * `labels`: Supports key-value equality as well as key presence.
  // * `featurestore_id`: Supports = comparisons.
  //
  // Examples:
  // * `description = "foo bar"` --> Any Feature with description exactly equal
  // to `foo bar`
  // * `value_type = DOUBLE` --> Features whose type is DOUBLE.
  // * `labels.active = yes AND labels.env = prod` --> Features having both
  //     (active: yes) and (env: prod) labels.
  // * `labels.env: *` --> Any Feature which has a label with `env` as the
  //   key.
  string query = 3;

  // The maximum number of Features to return. The service may return fewer
  // than this value. If unspecified, at most 100 Features will be returned.
  // The maximum value is 100; any value greater than 100 will be coerced to
  // 100.
  int32 page_size = 4;

  // A page token, received from a previous
  // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.SearchFeatures] call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.SearchFeatures], except `page_size`, must
  // match the call that provided the page token.
  string page_token = 5;
}

// Response message for [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1beta1.FeaturestoreService.SearchFeatures].
message SearchFeaturesResponse {
  // The Features matching the request.
  //
  // Fields returned:
  //
  //  * `name`
  //  * `description`
  //  * `labels`
  //  * `create_time`
  //  * `update_time`
  repeated Feature features = 1;

  // A token, which can be sent as [SearchFeaturesRequest.page_token][google.cloud.aiplatform.v1beta1.SearchFeaturesRequest.page_token] to
  // retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for [FeaturestoreService.UpdateFeature][google.cloud.aiplatform.v1beta1.FeaturestoreService.UpdateFeature].
message UpdateFeatureRequest {
  // Required. The Feature's `name` field is used to identify the Feature to be
  // updated.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}/features/{feature}`
  Feature feature = 1 [(google.api.field_behavior) = REQUIRED];

  // Field mask is used to specify the fields to be overwritten in the
  // Features resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then only the non-empty fields present in the
  // request will be overwritten. Set the update_mask to `*` to override all
  // fields.
  //
  // Updatable fields:
  //
  //   * `description`
  //   * `labels`
  //   * `monitoring_config.snapshot_analysis.disabled`
  //   * `monitoring_config.snapshot_analysis.monitoring_interval`
  google.protobuf.FieldMask update_mask = 2;
}

// Request message for [FeaturestoreService.DeleteFeature][google.cloud.aiplatform.v1beta1.FeaturestoreService.DeleteFeature].
message DeleteFeatureRequest {
  // Required. The name of the Features to be deleted.
  // Format:
  // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}/features/{feature}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Feature"
    }
  ];
}

// Details of operations that perform create Featurestore.
message CreateFeaturestoreOperationMetadata {
  // Operation metadata for Featurestore.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that perform update Featurestore.
message UpdateFeaturestoreOperationMetadata {
  // Operation metadata for Featurestore.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that perform import feature values.
message ImportFeatureValuesOperationMetadata {
  // Operation metadata for Featurestore import feature values.
  GenericOperationMetadata generic_metadata = 1;

  // Number of entities that have been imported by the operation.
  int64 imported_entity_count = 2;

  // Number of feature values that have been imported by the operation.
  int64 imported_feature_value_count = 3;

  // The number of rows in input source that weren't imported due to either
  // * Not having any featureValues.
  // * Having a null entityId.
  // * Having a null timestamp.
  // * Not being parsable (applicable for CSV sources).
  int64 invalid_row_count = 6;
}

// Details of operations that exports Features values.
message ExportFeatureValuesOperationMetadata {
  // Operation metadata for Featurestore export Feature values.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that batch reads Feature values.
message BatchReadFeatureValuesOperationMetadata {
  // Operation metadata for Featurestore batch read Features values.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that perform create EntityType.
message CreateEntityTypeOperationMetadata {
  // Operation metadata for EntityType.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that perform create Feature.
message CreateFeatureOperationMetadata {
  // Operation metadata for Feature.
  GenericOperationMetadata generic_metadata = 1;
}

// Details of operations that perform batch create Features.
message BatchCreateFeaturesOperationMetadata {
  // Operation metadata for Feature.
  GenericOperationMetadata generic_metadata = 1;
}
