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

import "google/api/field_behavior.proto";
import "google/protobuf/wrappers.proto";

option csharp_namespace = "Google.Cloud.BigQuery.Storage.V1";
option go_package = "cloud.google.com/go/bigquery/storage/apiv1/storagepb;storagepb";
option java_multiple_files = true;
option java_outer_classname = "TableProto";
option java_package = "com.google.cloud.bigquery.storage.v1";
option php_namespace = "Google\\Cloud\\BigQuery\\Storage\\V1";

// Schema of a table. This schema is a subset of
// google.cloud.bigquery.v2.TableSchema containing information necessary to
// generate valid message to write to BigQuery.
message TableSchema {
  // Describes the fields in a table.
  repeated TableFieldSchema fields = 1;
}

// TableFieldSchema defines a single field/column within a table schema.
message TableFieldSchema {
  enum Type {
    // Illegal value
    TYPE_UNSPECIFIED = 0;

    // 64K, UTF8
    STRING = 1;

    // 64-bit signed
    INT64 = 2;

    // 64-bit IEEE floating point
    DOUBLE = 3;

    // Aggregate type
    STRUCT = 4;

    // 64K, Binary
    BYTES = 5;

    // 2-valued
    BOOL = 6;

    // 64-bit signed usec since UTC epoch
    TIMESTAMP = 7;

    // Civil date - Year, Month, Day
    DATE = 8;

    // Civil time - Hour, Minute, Second, Microseconds
    TIME = 9;

    // Combination of civil date and civil time
    DATETIME = 10;

    // Geography object
    GEOGRAPHY = 11;

    // Numeric value
    NUMERIC = 12;

    // BigNumeric value
    BIGNUMERIC = 13;

    // Interval
    INTERVAL = 14;

    // JSON, String
    JSON = 15;

    // RANGE
    RANGE = 16;
  }

  enum Mode {
    // Illegal value
    MODE_UNSPECIFIED = 0;

    NULLABLE = 1;

    REQUIRED = 2;

    REPEATED = 3;
  }

  // Represents the type of a field element.
  message FieldElementType {
    // Required. The type of a field element.
    Type type = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // Required. The field name. The name must contain only letters (a-z, A-Z),
  // numbers (0-9), or underscores (_), and must start with a letter or
  // underscore. The maximum length is 128 characters.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The field data type.
  Type type = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The field mode. The default value is NULLABLE.
  Mode mode = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Describes the nested schema fields if the type property is set to
  // STRUCT.
  repeated TableFieldSchema fields = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The field description. The maximum length is 1,024 characters.
  string description = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Maximum length of values of this field for STRINGS or BYTES.
  //
  // If max_length is not specified, no maximum length constraint is imposed
  // on this field.
  //
  // If type = "STRING", then max_length represents the maximum UTF-8
  // length of strings in this field.
  //
  // If type = "BYTES", then max_length represents the maximum number of
  // bytes in this field.
  //
  // It is invalid to set this field if type is not "STRING" or "BYTES".
  int64 max_length = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Precision (maximum number of total digits in base 10) and scale
  // (maximum number of digits in the fractional part in base 10) constraints
  // for values of this field for NUMERIC or BIGNUMERIC.
  //
  // It is invalid to set precision or scale if type is not "NUMERIC" or
  // "BIGNUMERIC".
  //
  // If precision and scale are not specified, no value range constraint is
  // imposed on this field insofar as values are permitted by the type.
  //
  // Values of this NUMERIC or BIGNUMERIC field must be in this range when:
  //
  // * Precision (P) and scale (S) are specified:
  //   [-10^(P-S) + 10^(-S), 10^(P-S) - 10^(-S)]
  // * Precision (P) is specified but not scale (and thus scale is
  //   interpreted to be equal to zero):
  //   [-10^P + 1, 10^P - 1].
  //
  // Acceptable values for precision and scale if both are specified:
  //
  // * If type = "NUMERIC":
  //   1 <= precision - scale <= 29 and 0 <= scale <= 9.
  // * If type = "BIGNUMERIC":
  //   1 <= precision - scale <= 38 and 0 <= scale <= 38.
  //
  // Acceptable values for precision if only precision is specified but not
  // scale (and thus scale is interpreted to be equal to zero):
  //
  // * If type = "NUMERIC": 1 <= precision <= 29.
  // * If type = "BIGNUMERIC": 1 <= precision <= 38.
  //
  // If scale is specified but not precision, then it is invalid.
  int64 precision = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. See documentation for precision.
  int64 scale = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A SQL expression to specify the [default value]
  // (https://cloud.google.com/bigquery/docs/default-values) for this field.
  string default_value_expression = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Precision (maximum number of total digits in base 10) for seconds
  // of TIMESTAMP type.
  //
  // Possible values include:
  //
  // * 6 (Default, for TIMESTAMP type with microsecond precision)
  // * 12 (For TIMESTAMP type with picosecond precision)
  google.protobuf.Int64Value timestamp_precision = 27
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The subtype of the RANGE, if the type of this field is RANGE. If
  // the type is RANGE, this field is required. Possible values for the field
  // element type of a RANGE include:
  // * DATE
  // * DATETIME
  // * TIMESTAMP
  FieldElementType range_element_type = 11
      [(google.api.field_behavior) = OPTIONAL];
}
