// 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.discoveryengine.v1alpha;

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

option csharp_namespace = "Google.Cloud.DiscoveryEngine.V1Alpha";
option go_package = "cloud.google.com/go/discoveryengine/apiv1alpha/discoveryenginepb;discoveryenginepb";
option java_multiple_files = true;
option java_outer_classname = "SchemaProto";
option java_package = "com.google.cloud.discoveryengine.v1alpha";
option objc_class_prefix = "DISCOVERYENGINE";
option php_namespace = "Google\\Cloud\\DiscoveryEngine\\V1alpha";
option ruby_package = "Google::Cloud::DiscoveryEngine::V1alpha";

// Defines the structure and layout of a type of document data.
message Schema {
  option (google.api.resource) = {
    type: "discoveryengine.googleapis.com/Schema"
    pattern: "projects/{project}/locations/{location}/dataStores/{data_store}/schemas/{schema}"
    pattern: "projects/{project}/locations/{location}/collections/{collection}/dataStores/{data_store}/schemas/{schema}"
  };

  // Schema representation. One of
  // [struct_schema][google.cloud.discoveryengine.v1alpha.Schema.struct_schema]
  // or [json_schema][google.cloud.discoveryengine.v1alpha.Schema.json_schema]
  // should be provided otherwise an `INVALID_ARGUMENT` error is thrown.
  oneof schema {
    // The structured representation of the schema.
    google.protobuf.Struct struct_schema = 2;

    // The JSON representation of the schema.
    string json_schema = 3;
  }

  // Immutable. The full resource name of the schema, in the format of
  // `projects/{project}/locations/{location}/collections/{collection}/dataStores/{data_store}/schemas/{schema}`.
  //
  // This field must be a UTF-8 encoded string with a length limit of 1024
  // characters.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. Configurations for fields of the schema.
  repeated FieldConfig field_configs = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Configurations for fields of a schema. For example, configuring a field is
// indexable, or searchable.
message FieldConfig {
  // Field value type in the Schema.
  enum FieldType {
    // Field type is unspecified.
    FIELD_TYPE_UNSPECIFIED = 0;

    // Field value type is Object.
    OBJECT = 1;

    // Field value type is String.
    STRING = 2;

    // Field value type is Number.
    NUMBER = 3;

    // Field value type is Integer.
    INTEGER = 4;

    // Field value type is Boolean.
    BOOLEAN = 5;

    // Field value type is Geolocation. Geolocation is expressed as an object
    // with the following keys:
    //
    // * `id`: a string representing the location id
    // * `longitude`: a number representing the longitude coordinate of the
    // location
    // * `latitude`: a number repesenting the latitude coordinate of the
    // location
    // * `address`: a string representing the full address of the location
    //
    // `latitude` and `longitude` must always be provided together. At least one
    // of a) `address` or b) `latitude`-`longitude` pair must be provided.
    GEOLOCATION = 6;

    // Field value type is Datetime. Datetime can be expressed as either:
    //
    // * a number representing milliseconds-since-the-epoch
    // * a string representing milliseconds-since-the-epoch. e.g.
    // `"1420070400001"`
    // * a string representing the [ISO
    // 8601](https://en.wikipedia.org/wiki/ISO_8601) date or date and time. e.g.
    // `"2015-01-01"` or `"2015-01-01T12:10:30Z"`
    DATETIME = 7;
  }

  // The setting of Indexable options in schema.
  enum IndexableOption {
    // Value used when unset.
    INDEXABLE_OPTION_UNSPECIFIED = 0;

    // Indexable option enabled for a schema field.
    INDEXABLE_ENABLED = 1;

    // Indexable option disabled for a schema field.
    INDEXABLE_DISABLED = 2;
  }

  // The status of the dynamic facetable option of a schema field.
  enum DynamicFacetableOption {
    // Value used when unset.
    DYNAMIC_FACETABLE_OPTION_UNSPECIFIED = 0;

    // Dynamic facetable option enabled for a schema field.
    DYNAMIC_FACETABLE_ENABLED = 1;

    // Dynamic facetable option disabled for a schema field.
    DYNAMIC_FACETABLE_DISABLED = 2;
  }

  // The setting of Searchable options in schema.
  enum SearchableOption {
    // Value used when unset.
    SEARCHABLE_OPTION_UNSPECIFIED = 0;

    // Searchable option enabled for a schema field.
    SEARCHABLE_ENABLED = 1;

    // Searchable option disabled for a schema field.
    SEARCHABLE_DISABLED = 2;
  }

  // The setting of Retrievable options in schema.
  enum RetrievableOption {
    // Value used when unset.
    RETRIEVABLE_OPTION_UNSPECIFIED = 0;

    // Retrievable option enabled for a schema field.
    RETRIEVABLE_ENABLED = 1;

    // Retrievable option disabled for a schema field.
    RETRIEVABLE_DISABLED = 2;
  }

  // The setting of Completable options in schema.
  enum CompletableOption {
    // Value used when unset.
    COMPLETABLE_OPTION_UNSPECIFIED = 0;

    // Completable option enabled for a schema field.
    COMPLETABLE_ENABLED = 1;

    // Completable option disabled for a schema field.
    COMPLETABLE_DISABLED = 2;
  }

  // Sets the filterable option for schema fields.
  enum FilterableOption {
    // Value used when unset.
    FILTERABLE_OPTION_UNSPECIFIED = 0;

    // Filterable option enabled for a schema field.
    FILTERABLE_ENABLED = 1;

    // Filterable option disabled for a schema field.
    FILTERABLE_DISABLED = 2;
  }

  // Optional source of the advanced site search field.
  enum AdvancedSiteSearchDataSource {
    // Value used when unset.
    ADVANCED_SITE_SEARCH_DATA_SOURCE_UNSPECIFIED = 0;

    // Retrieve value from meta tag.
    METATAGS = 1;

    // Retrieve value from page map.
    PAGEMAP = 2;

    // Retrieve value from the attributes set by
    // [SiteSearchEngineService.SetUriPatternDocumentData][google.cloud.discoveryengine.v1alpha.SiteSearchEngineService.SetUriPatternDocumentData]
    // API.
    URI_PATTERN_MAPPING = 3;

    // Retrieve value from schema.org data.
    SCHEMA_ORG = 4;
  }

  // Required. Field path of the schema field.
  // For example: `title`, `description`, `release_info.release_year`.
  string field_path = 1 [(google.api.field_behavior) = REQUIRED];

  // Output only. Raw type of the field.
  FieldType field_type = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // If
  // [indexable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.indexable_option]
  // is
  // [INDEXABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.IndexableOption.INDEXABLE_ENABLED],
  // field values are indexed so that it can be filtered or faceted in
  // [SearchService.Search][google.cloud.discoveryengine.v1alpha.SearchService.Search].
  //
  // If
  // [indexable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.indexable_option]
  // is unset, the server behavior defaults to
  // [INDEXABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.IndexableOption.INDEXABLE_DISABLED]
  // for fields that support setting indexable options. For those fields that do
  // not support setting indexable options, such as `object` and `boolean` and
  // key properties, the server will skip
  // [indexable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.indexable_option]
  // setting, and setting
  // [indexable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.indexable_option]
  // for those fields will throw `INVALID_ARGUMENT` error.
  IndexableOption indexable_option = 3;

  // If
  // [dynamic_facetable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.dynamic_facetable_option]
  // is
  // [DYNAMIC_FACETABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.DynamicFacetableOption.DYNAMIC_FACETABLE_ENABLED],
  // field values are available for dynamic facet. Could only be
  // [DYNAMIC_FACETABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.DynamicFacetableOption.DYNAMIC_FACETABLE_DISABLED]
  // if
  // [FieldConfig.indexable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.indexable_option]
  // is
  // [INDEXABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.IndexableOption.INDEXABLE_DISABLED].
  // Otherwise, an `INVALID_ARGUMENT` error will be returned.
  //
  // If
  // [dynamic_facetable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.dynamic_facetable_option]
  // is unset, the server behavior defaults to
  // [DYNAMIC_FACETABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.DynamicFacetableOption.DYNAMIC_FACETABLE_DISABLED]
  // for fields that support setting dynamic facetable options. For those fields
  // that do not support setting dynamic facetable options, such as `object` and
  // `boolean`, the server will skip dynamic facetable option setting, and
  // setting
  // [dynamic_facetable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.dynamic_facetable_option]
  // for those fields will throw `INVALID_ARGUMENT` error.
  DynamicFacetableOption dynamic_facetable_option = 4;

  // If
  // [searchable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.searchable_option]
  // is
  // [SEARCHABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.SearchableOption.SEARCHABLE_ENABLED],
  // field values are searchable by text queries in
  // [SearchService.Search][google.cloud.discoveryengine.v1alpha.SearchService.Search].
  //
  // If
  // [SEARCHABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.SearchableOption.SEARCHABLE_ENABLED]
  // but field type is numerical, field values will not be searchable by text
  // queries in
  // [SearchService.Search][google.cloud.discoveryengine.v1alpha.SearchService.Search],
  // as there are no text values associated to numerical fields.
  //
  // If
  // [searchable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.searchable_option]
  // is unset, the server behavior defaults to
  // [SEARCHABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.SearchableOption.SEARCHABLE_DISABLED]
  // for fields that support setting searchable options. Only `string` fields
  // that have no key property mapping support setting
  // [searchable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.searchable_option].
  //
  // For those fields that do not support setting searchable options, the server
  // will skip searchable option setting, and setting
  // [searchable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.searchable_option]
  // for those fields will throw `INVALID_ARGUMENT` error.
  SearchableOption searchable_option = 5;

  // If
  // [retrievable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.retrievable_option]
  // is
  // [RETRIEVABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.RetrievableOption.RETRIEVABLE_ENABLED],
  // field values are included in the search results.
  //
  // If
  // [retrievable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.retrievable_option]
  // is unset, the server behavior defaults to
  // [RETRIEVABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.RetrievableOption.RETRIEVABLE_DISABLED]
  // for fields that support setting retrievable options. For those fields
  // that do not support setting retrievable options, such as `object` and
  // `boolean`, the server will skip retrievable option setting, and setting
  // [retrievable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.retrievable_option]
  // for those fields will throw `INVALID_ARGUMENT` error.
  RetrievableOption retrievable_option = 6;

  // If
  // [completable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.completable_option]
  // is
  // [COMPLETABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.CompletableOption.COMPLETABLE_ENABLED],
  // field values are directly used and returned as suggestions for Autocomplete
  // in
  // [CompletionService.CompleteQuery][google.cloud.discoveryengine.v1alpha.CompletionService.CompleteQuery].
  //
  // If
  // [completable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.completable_option]
  // is unset, the server behavior defaults to
  // [COMPLETABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.CompletableOption.COMPLETABLE_DISABLED]
  // for fields that support setting completable options, which are just
  // `string` fields. For those fields that do not support setting completable
  // options, the server will skip completable option setting, and setting
  // [completable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.completable_option]
  // for those fields will throw `INVALID_ARGUMENT` error.
  CompletableOption completable_option = 8;

  // If
  // [recs_filterable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.recs_filterable_option]
  // is
  // [FILTERABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.FilterableOption.FILTERABLE_ENABLED],
  // field values are filterable by filter expression in
  // [RecommendationService.Recommend][google.cloud.discoveryengine.v1alpha.RecommendationService.Recommend].
  //
  // If
  // [FILTERABLE_ENABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.FilterableOption.FILTERABLE_ENABLED]
  // but the field type is numerical, field values are not filterable by text
  // queries in
  // [RecommendationService.Recommend][google.cloud.discoveryengine.v1alpha.RecommendationService.Recommend].
  // Only textual fields are supported.
  //
  // If
  // [recs_filterable_option][google.cloud.discoveryengine.v1alpha.FieldConfig.recs_filterable_option]
  // is unset, the default setting is
  // [FILTERABLE_DISABLED][google.cloud.discoveryengine.v1alpha.FieldConfig.FilterableOption.FILTERABLE_DISABLED]
  // for fields that support setting filterable options.
  //
  // When a field set to [FILTERABLE_DISABLED] is filtered, a warning is
  // generated and an empty result is returned.
  FilterableOption recs_filterable_option = 9;

  // Output only. Type of the key property that this field is mapped to. Empty
  // string if this is not annotated as mapped to a key property.
  //
  // Example types are `title`, `description`. Full list is defined
  // by `keyPropertyMapping` in the schema field annotation.
  //
  // If the schema field has a `KeyPropertyMapping` annotation,
  // `indexable_option` and `searchable_option` of this field cannot be
  // modified.
  string key_property_type = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // If this field is set, only the corresponding source will be indexed for
  // this field. Otherwise, the values from different sources are merged.
  //
  // Assuming a page with `<author, a>` in meta tag, and `<author, b>` in page
  // map:
  //  if this enum is set to METATAGS, we will only index `<author, a>`;
  //  if this enum is not set, we will merge them and index `<author, [a, b]>`.
  repeated AdvancedSiteSearchDataSource advanced_site_search_data_sources = 10;

  // Field paths for indexing custom attribute from schema.org data. More
  // details of schema.org and its defined types can be found at
  // [schema.org](https://schema.org).
  //
  // It is only used on advanced site search schema.
  //
  // Currently only support full path from root. The full path to a field is
  // constructed by concatenating field names, starting from `_root`, with
  // a period `.` as the delimiter. Examples:
  //
  // * Publish date of the root: _root.datePublished
  // * Publish date of the reviews: _root.review.datePublished
  repeated string schema_org_paths = 11;
}
