// Code generated by sidekick. DO NOT EDIT.
//
// Copyright 2026 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
//
//     https://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.

import Foundation
import GoogleCloudWkt
import GoogleType

/// BigQuery source import data from.
public struct BigQuerySource: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// The project ID (can be project # or ID) that the BigQuery source is in with
  /// a length limit of 128 characters. If not specified, inherits the project
  /// ID from the parent request.
  public var projectId: Swift.String = Swift.String()

  /// Required. The BigQuery data set to copy the data from with a length limit
  /// of 1,024 characters.
  public var datasetId: Swift.String = Swift.String()

  /// Required. The BigQuery table to copy the data from with a length limit of
  /// 1,024 characters.
  public var tableId: Swift.String = Swift.String()

  /// Intermediate Cloud Storage directory used for the import with a length
  /// limit of 2,000 characters. Can be specified if one wants to have the
  /// BigQuery export to a specific Cloud Storage directory.
  public var gcsStagingDir: Swift.String = Swift.String()

  /// The schema to use when parsing the data from the source.
  ///
  /// Supported values for product imports:
  ///
  /// * `product` (default): One JSON [Product][google.cloud.retail.v2.Product]
  /// per line. Each product must
  ///   have a valid [Product.id][google.cloud.retail.v2.Product.id].
  /// * `product_merchant_center`: See [Importing catalog data from Merchant
  ///   Center](https://cloud.google.com/retail/recommendations-ai/docs/upload-catalog#mc).
  ///
  /// Supported values for user events imports:
  ///
  /// * `user_event` (default): One JSON
  /// [UserEvent][google.cloud.retail.v2.UserEvent] per line.
  /// * `user_event_ga360`:
  ///   The schema is available here:
  ///   https://support.google.com/analytics/answer/3437719.
  /// * `user_event_ga4`:
  ///   The schema is available here:
  ///   https://support.google.com/analytics/answer/7029846.
  ///
  /// Supported values for autocomplete imports:
  ///
  /// * `suggestions` (default): One JSON completion suggestion per line.
  /// * `denylist`:  One JSON deny suggestion per line.
  /// * `allowlist`:  One JSON allow suggestion per line.
  ///
  /// [google.cloud.retail.v2.Product]: <doc:Product>
  /// [google.cloud.retail.v2.Product.id]: <doc:Product/id>
  /// [google.cloud.retail.v2.UserEvent]: <doc:UserEvent>
  public var dataSchema: Swift.String = Swift.String()

  /// BigQuery table partition info. Leave this empty if the BigQuery table
  /// is not partitioned.
  public var partition: OneOf_Partition? = nil

  /// Initialize a new instance of `BigQuerySource`.
  public init() {}

  /// Use `config` to return a new instance of this object, with some fields updated.
  ///
  /// Commonly used to initialize the value, for example:
  ///
  /// ```
  /// let value = BigQuerySource().with { $0.partitionDate = ... }
  /// ```
  public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
    var copy = self
    try config(&copy)
    return copy
  }

  private enum CodingKeys: Swift.String, CodingKey {
    case partitionDate = "partitionDate"
    case projectId = "projectId"
    case datasetId = "datasetId"
    case tableId = "tableId"
    case gcsStagingDir = "gcsStagingDir"
    case dataSchema = "dataSchema"
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.projectId = try container.decode(Swift.String.self, forKey: .projectId)
    self.datasetId = try container.decode(Swift.String.self, forKey: .datasetId)
    self.tableId = try container.decode(Swift.String.self, forKey: .tableId)
    self.gcsStagingDir = try container.decode(Swift.String.self, forKey: .gcsStagingDir)
    self.dataSchema = try container.decode(Swift.String.self, forKey: .dataSchema)

    var partition: OneOf_Partition? = nil
    let partitionCheckAndSet = {
      if partition != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'partition'"))
      }
      partition = $0
    }
    if let partitionDate = try container.decodeIfPresent(
      GoogleType.Date?.self, forKey: .partitionDate)
    {
      try partitionCheckAndSet(.partitionDate(partitionDate))
    }
    self.partition = partition
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.projectId, forKey: .projectId)
    try container.encode(self.datasetId, forKey: .datasetId)
    try container.encode(self.tableId, forKey: .tableId)
    try container.encode(self.gcsStagingDir, forKey: .gcsStagingDir)
    try container.encode(self.dataSchema, forKey: .dataSchema)

    if let choice = self.partition {
      switch choice {
      case .partitionDate(let value):
        try container.encode(value, forKey: .partitionDate)
      }
    }
  }

  /// BigQuery table partition info. Leave this empty if the BigQuery table
  /// is not partitioned.
  public enum OneOf_Partition: Codable, Equatable, Sendable {
    /// BigQuery time partitioned table's _PARTITIONDATE in YYYY-MM-DD format.
    indirect case partitionDate(GoogleType.Date?)
  }

  public static var _anyTypeUrl: Swift.String {
    return "type.googleapis.com/google.cloud.retail.v2.BigQuerySource"
  }
  public init(fromAny any: GoogleCloudWkt.`Any`) throws {
    self = try GoogleCloudWkt._slowAnyDeserialize(Self.self, from: any)
  }
  public func _pack() throws -> GoogleCloudWkt.Struct {
    return try GoogleCloudWkt._slowAnySerialize(message: self)
  }
}
