// 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.
//
// ** This file is automatically generated by gapic-generator-typescript. **
// ** https://github.com/googleapis/gapic-generator-typescript **
// ** All changes to this file may be overwritten. **

/* global window */
import type * as gax from 'google-gax';
import type {
  Callback,
  CallOptions,
  Descriptors,
  ClientOptions,
  GrpcClientOptions,
  LROperation,
  PaginationCallback,
  GaxCall,
} from 'google-gax';
import {Transform} from 'stream';
import * as protos from '../../protos/protos';
import jsonProtos = require('../../protos/protos.json');
import {loggingUtils as logging, decodeAnyProtosInArray} from 'google-gax';

/**
 * Client JSON configuration object, loaded from
 * `src/v1/database_admin_client_config.json`.
 * This file defines retry strategy and timeouts for all API methods in this library.
 */
import * as gapicConfig from './database_admin_client_config.json';
const version = require('../../../package.json').version;

/**
 *  Cloud Spanner Database Admin API
 *
 *  The Cloud Spanner Database Admin API can be used to:
 *    * create, drop, and list databases
 *    * update the schema of pre-existing databases
 *    * create, delete, copy and list backups for a database
 *    * restore a database from an existing backup
 * @class
 * @memberof v1
 */
export class DatabaseAdminClient {
  private _terminated = false;
  private _opts: ClientOptions;
  private _providedCustomServicePath: boolean;
  private _gaxModule: typeof gax | typeof gax.fallback;
  private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient;
  private _protos: {};
  private _defaults: {[method: string]: gax.CallSettings};
  private _universeDomain: string;
  private _servicePath: string;
  private _log = logging.log('spanner');

  auth: gax.GoogleAuth;
  descriptors: Descriptors = {
    page: {},
    stream: {},
    longrunning: {},
    batching: {},
  };
  warn: (code: string, message: string, warnType?: string) => void;
  innerApiCalls: {[name: string]: Function};
  pathTemplates: {[name: string]: gax.PathTemplate};
  operationsClient: gax.OperationsClient;
  databaseAdminStub?: Promise<{[name: string]: Function}>;

  /**
   * Construct an instance of DatabaseAdminClient.
   *
   * @param {object} [options] - The configuration object.
   * The options accepted by the constructor are described in detail
   * in [this document](https://github.com/googleapis/gax-nodejs/blob/main/client-libraries.md#creating-the-client-instance).
   * The common options are:
   * @param {object} [options.credentials] - Credentials object.
   * @param {string} [options.credentials.client_email]
   * @param {string} [options.credentials.private_key]
   * @param {string} [options.email] - Account email address. Required when
   *     using a .pem or .p12 keyFilename.
   * @param {string} [options.keyFilename] - Full path to the a .json, .pem, or
   *     .p12 key downloaded from the Google Developers Console. If you provide
   *     a path to a JSON file, the projectId option below is not necessary.
   *     NOTE: .pem and .p12 require you to specify options.email as well.
   * @param {number} [options.port] - The port on which to connect to
   *     the remote host.
   * @param {string} [options.projectId] - The project ID from the Google
   *     Developer's Console, e.g. 'grape-spaceship-123'. We will also check
   *     the environment variable GCLOUD_PROJECT for your project ID. If your
   *     app is running in an environment which supports
   *     {@link https://cloud.google.com/docs/authentication/application-default-credentials Application Default Credentials},
   *     your project ID will be detected automatically.
   * @param {string} [options.apiEndpoint] - The domain name of the
   *     API remote host.
   * @param {gax.ClientConfig} [options.clientConfig] - Client configuration override.
   *     Follows the structure of {@link gapicConfig}.
   * @param {boolean} [options.fallback] - Use HTTP/1.1 REST mode.
   *     For more information, please check the
   *     {@link https://github.com/googleapis/gax-nodejs/blob/main/client-libraries.md#http11-rest-api-mode documentation}.
   * @param {gax} [gaxInstance]: loaded instance of `google-gax`. Useful if you
   *     need to avoid loading the default gRPC version and want to use the fallback
   *     HTTP implementation. Load only fallback version and pass it to the constructor:
   *     ```
   *     const gax = require('google-gax/build/src/fallback'); // avoids loading google-gax with gRPC
   *     const client = new DatabaseAdminClient({fallback: true}, gax);
   *     ```
   */
  constructor(
    opts?: ClientOptions,
    gaxInstance?: typeof gax | typeof gax.fallback,
  ) {
    // Ensure that options include all the required fields.
    const staticMembers = this.constructor as typeof DatabaseAdminClient;
    if (
      opts?.universe_domain &&
      opts?.universeDomain &&
      opts?.universe_domain !== opts?.universeDomain
    ) {
      throw new Error(
        'Please set either universe_domain or universeDomain, but not both.',
      );
    }
    const universeDomainEnvVar =
      typeof process === 'object' && typeof process.env === 'object'
        ? process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN']
        : undefined;
    this._universeDomain =
      opts?.universeDomain ??
      opts?.universe_domain ??
      universeDomainEnvVar ??
      'googleapis.com';
    this._servicePath = 'spanner.' + this._universeDomain;
    const servicePath =
      opts?.servicePath || opts?.apiEndpoint || this._servicePath;
    this._providedCustomServicePath = !!(
      opts?.servicePath || opts?.apiEndpoint
    );
    const port = opts?.port || staticMembers.port;
    const clientConfig = opts?.clientConfig ?? {};
    const fallback =
      opts?.fallback ??
      (typeof window !== 'undefined' && typeof window?.fetch === 'function');
    opts = Object.assign({servicePath, port, clientConfig, fallback}, opts);

    // Request numeric enum values if REST transport is used.
    opts.numericEnums = true;

    // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case.
    if (servicePath !== this._servicePath && !('scopes' in opts)) {
      opts['scopes'] = staticMembers.scopes;
    }

    // Load google-gax module synchronously if needed
    if (!gaxInstance) {
      gaxInstance = require('google-gax') as typeof gax;
    }

    // Choose either gRPC or proto-over-HTTP implementation of google-gax.
    this._gaxModule = opts.fallback ? gaxInstance.fallback : gaxInstance;

    // Create a `gaxGrpc` object, with any grpc-specific options sent to the client.
    this._gaxGrpc = new this._gaxModule.GrpcClient(opts);

    // Save options to use in initialize() method.
    this._opts = opts;

    // Save the auth object to the client, for use by other methods.
    this.auth = this._gaxGrpc.auth as gax.GoogleAuth;

    // Set useJWTAccessWithScope on the auth object.
    this.auth.useJWTAccessWithScope = true;

    // Set defaultServicePath on the auth object.
    this.auth.defaultServicePath = this._servicePath;

    // Set the default scopes in auth client if needed.
    if (servicePath === this._servicePath) {
      this.auth.defaultScopes = staticMembers.scopes;
    }

    // Determine the client header string.
    const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`];
    if (typeof process === 'object' && 'versions' in process) {
      clientHeader.push(`gl-node/${process.versions.node}`);
    } else {
      clientHeader.push(`gl-web/${this._gaxModule.version}`);
    }
    if (!opts.fallback) {
      clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`);
    } else {
      clientHeader.push(`rest/${this._gaxGrpc.grpcVersion}`);
    }
    if (opts.libName && opts.libVersion) {
      clientHeader.push(`${opts.libName}/${opts.libVersion}`);
    }
    // Load the applicable protos.
    this._protos = this._gaxGrpc.loadProtoJSON(jsonProtos);

    // This API contains "path templates"; forward-slash-separated
    // identifiers to uniquely identify resources within the API.
    // Create useful helper objects for these.
    this.pathTemplates = {
      backupPathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/instances/{instance}/backups/{backup}',
      ),
      backupSchedulePathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/instances/{instance}/databases/{database}/backupSchedules/{schedule}',
      ),
      cryptoKeyPathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}',
      ),
      databasePathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/instances/{instance}/databases/{database}',
      ),
      databaseRolePathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/instances/{instance}/databases/{database}/databaseRoles/{role}',
      ),
      instancePathTemplate: new this._gaxModule.PathTemplate(
        'projects/{project}/instances/{instance}',
      ),
    };

    // Some of the methods on this service return "paged" results,
    // (e.g. 50 results at a time, with tokens to get subsequent
    // pages). Denote the keys used for pagination and results.
    this.descriptors.page = {
      listDatabases: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'databases',
      ),
      listBackups: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'backups',
      ),
      listDatabaseOperations: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'operations',
      ),
      listBackupOperations: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'operations',
      ),
      listDatabaseRoles: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'databaseRoles',
      ),
      listBackupSchedules: new this._gaxModule.PageDescriptor(
        'pageToken',
        'nextPageToken',
        'backupSchedules',
      ),
    };

    const protoFilesRoot = this._gaxModule.protobufFromJSON(jsonProtos);
    // This API contains "long-running operations", which return a
    // an Operation object that allows for tracking of the operation,
    // rather than holding a request open.
    const lroOptions: GrpcClientOptions = {
      auth: this.auth,
      grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined,
    };
    if (opts.fallback) {
      lroOptions.protoJson = protoFilesRoot;
      lroOptions.httpRules = [
        {
          selector: 'google.longrunning.Operations.CancelOperation',
          post: '/v1/{name=projects/*/instances/*/databases/*/operations/*}:cancel',
          additional_bindings: [
            {post: '/v1/{name=projects/*/instances/*/operations/*}:cancel'},
            {
              post: '/v1/{name=projects/*/instances/*/backups/*/operations/*}:cancel',
            },
            {
              post: '/v1/{name=projects/*/instanceConfigs/*/operations/*}:cancel',
            },
          ],
        },
        {
          selector: 'google.longrunning.Operations.DeleteOperation',
          delete: '/v1/{name=projects/*/instances/*/databases/*/operations/*}',
          additional_bindings: [
            {delete: '/v1/{name=projects/*/instances/*/operations/*}'},
            {
              delete:
                '/v1/{name=projects/*/instances/*/backups/*/operations/*}',
            },
            {delete: '/v1/{name=projects/*/instanceConfigs/*/operations/*}'},
          ],
        },
        {
          selector: 'google.longrunning.Operations.GetOperation',
          get: '/v1/{name=projects/*/instances/*/databases/*/operations/*}',
          additional_bindings: [
            {get: '/v1/{name=projects/*/instances/*/operations/*}'},
            {get: '/v1/{name=projects/*/instances/*/backups/*/operations/*}'},
            {get: '/v1/{name=projects/*/instanceConfigs/*/operations/*}'},
          ],
        },
        {
          selector: 'google.longrunning.Operations.ListOperations',
          get: '/v1/{name=projects/*/instances/*/databases/*/operations}',
          additional_bindings: [
            {get: '/v1/{name=projects/*/instances/*/operations}'},
            {get: '/v1/{name=projects/*/instances/*/backups/*/operations}'},
            {get: '/v1/{name=projects/*/instanceConfigs/*/operations}'},
          ],
        },
      ];
    }
    this.operationsClient = this._gaxModule
      .lro(lroOptions)
      .operationsClient(opts);
    const createDatabaseResponse = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.Database',
    ) as gax.protobuf.Type;
    const createDatabaseMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.CreateDatabaseMetadata',
    ) as gax.protobuf.Type;
    const updateDatabaseResponse = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.Database',
    ) as gax.protobuf.Type;
    const updateDatabaseMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.UpdateDatabaseMetadata',
    ) as gax.protobuf.Type;
    const updateDatabaseDdlResponse = protoFilesRoot.lookup(
      '.google.protobuf.Empty',
    ) as gax.protobuf.Type;
    const updateDatabaseDdlMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata',
    ) as gax.protobuf.Type;
    const createBackupResponse = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.Backup',
    ) as gax.protobuf.Type;
    const createBackupMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.CreateBackupMetadata',
    ) as gax.protobuf.Type;
    const copyBackupResponse = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.Backup',
    ) as gax.protobuf.Type;
    const copyBackupMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.CopyBackupMetadata',
    ) as gax.protobuf.Type;
    const restoreDatabaseResponse = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.Database',
    ) as gax.protobuf.Type;
    const restoreDatabaseMetadata = protoFilesRoot.lookup(
      '.google.spanner.admin.database.v1.RestoreDatabaseMetadata',
    ) as gax.protobuf.Type;

    this.descriptors.longrunning = {
      createDatabase: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        createDatabaseResponse.decode.bind(createDatabaseResponse),
        createDatabaseMetadata.decode.bind(createDatabaseMetadata),
      ),
      updateDatabase: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        updateDatabaseResponse.decode.bind(updateDatabaseResponse),
        updateDatabaseMetadata.decode.bind(updateDatabaseMetadata),
      ),
      updateDatabaseDdl: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        updateDatabaseDdlResponse.decode.bind(updateDatabaseDdlResponse),
        updateDatabaseDdlMetadata.decode.bind(updateDatabaseDdlMetadata),
      ),
      createBackup: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        createBackupResponse.decode.bind(createBackupResponse),
        createBackupMetadata.decode.bind(createBackupMetadata),
      ),
      copyBackup: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        copyBackupResponse.decode.bind(copyBackupResponse),
        copyBackupMetadata.decode.bind(copyBackupMetadata),
      ),
      restoreDatabase: new this._gaxModule.LongrunningDescriptor(
        this.operationsClient,
        restoreDatabaseResponse.decode.bind(restoreDatabaseResponse),
        restoreDatabaseMetadata.decode.bind(restoreDatabaseMetadata),
      ),
    };

    // Put together the default options sent with requests.
    this._defaults = this._gaxGrpc.constructSettings(
      'google.spanner.admin.database.v1.DatabaseAdmin',
      gapicConfig as gax.ClientConfig,
      opts.clientConfig || {},
      {'x-goog-api-client': clientHeader.join(' ')},
    );

    // Set up a dictionary of "inner API calls"; the core implementation
    // of calling the API is handled in `google-gax`, with this code
    // merely providing the destination and request information.
    this.innerApiCalls = {};

    // Add a warn function to the client constructor so it can be easily tested.
    this.warn = this._gaxModule.warn;
  }

  /**
   * Initialize the client.
   * Performs asynchronous operations (such as authentication) and prepares the client.
   * This function will be called automatically when any class method is called for the
   * first time, but if you need to initialize it before calling an actual method,
   * feel free to call initialize() directly.
   *
   * You can await on this method if you want to make sure the client is initialized.
   *
   * @returns {Promise} A promise that resolves to an authenticated service stub.
   */
  initialize() {
    // If the client stub promise is already initialized, return immediately.
    if (this.databaseAdminStub) {
      return this.databaseAdminStub;
    }

    // Put together the "service stub" for
    // google.spanner.admin.database.v1.DatabaseAdmin.
    this.databaseAdminStub = this._gaxGrpc.createStub(
      this._opts.fallback
        ? (this._protos as protobuf.Root).lookupService(
            'google.spanner.admin.database.v1.DatabaseAdmin',
          )
        : // eslint-disable-next-line @typescript-eslint/no-explicit-any
          (this._protos as any).google.spanner.admin.database.v1.DatabaseAdmin,
      this._opts,
      this._providedCustomServicePath,
    ) as Promise<{[method: string]: Function}>;

    // Iterate over each of the methods that the service provides
    // and create an API call method for each.
    const databaseAdminStubMethods = [
      'listDatabases',
      'createDatabase',
      'getDatabase',
      'updateDatabase',
      'updateDatabaseDdl',
      'dropDatabase',
      'getDatabaseDdl',
      'setIamPolicy',
      'getIamPolicy',
      'testIamPermissions',
      'createBackup',
      'copyBackup',
      'getBackup',
      'updateBackup',
      'deleteBackup',
      'listBackups',
      'restoreDatabase',
      'listDatabaseOperations',
      'listBackupOperations',
      'listDatabaseRoles',
      'addSplitPoints',
      'createBackupSchedule',
      'getBackupSchedule',
      'updateBackupSchedule',
      'deleteBackupSchedule',
      'listBackupSchedules',
      'internalUpdateGraphOperation',
    ];
    for (const methodName of databaseAdminStubMethods) {
      const callPromise = this.databaseAdminStub.then(
        stub =>
          (...args: Array<{}>) => {
            if (this._terminated) {
              return Promise.reject('The client has already been closed.');
            }
            const func = stub[methodName];
            return func.apply(stub, args);
          },
        (err: Error | null | undefined) => () => {
          throw err;
        },
      );

      const descriptor =
        this.descriptors.page[methodName] ||
        this.descriptors.longrunning[methodName] ||
        undefined;
      const apiCall = this._gaxModule.createApiCall(
        callPromise,
        this._defaults[methodName],
        descriptor,
        this._opts.fallback,
      );

      this.innerApiCalls[methodName] = apiCall;
    }

    return this.databaseAdminStub;
  }

  /**
   * The DNS address for this API service.
   * @deprecated Use the apiEndpoint method of the client instance.
   * @returns {string} The DNS address for this service.
   */
  static get servicePath() {
    if (
      typeof process === 'object' &&
      typeof process.emitWarning === 'function'
    ) {
      process.emitWarning(
        'Static servicePath is deprecated, please use the instance method instead.',
        'DeprecationWarning',
      );
    }
    return 'spanner.googleapis.com';
  }

  /**
   * The DNS address for this API service - same as servicePath.
   * @deprecated Use the apiEndpoint method of the client instance.
   * @returns {string} The DNS address for this service.
   */
  static get apiEndpoint() {
    if (
      typeof process === 'object' &&
      typeof process.emitWarning === 'function'
    ) {
      process.emitWarning(
        'Static apiEndpoint is deprecated, please use the instance method instead.',
        'DeprecationWarning',
      );
    }
    return 'spanner.googleapis.com';
  }

  /**
   * The DNS address for this API service.
   * @returns {string} The DNS address for this service.
   */
  get apiEndpoint() {
    return this._servicePath;
  }

  get universeDomain() {
    return this._universeDomain;
  }

  /**
   * The port for this API service.
   * @returns {number} The default port for this service.
   */
  static get port() {
    return 443;
  }

  /**
   * The scopes needed to make gRPC calls for every method defined
   * in this service.
   * @returns {string[]} List of default scopes.
   */
  static get scopes() {
    return [
      'https://www.googleapis.com/auth/cloud-platform',
      'https://www.googleapis.com/auth/spanner.admin',
    ];
  }

  getProjectId(): Promise<string>;
  getProjectId(callback: Callback<string, undefined, undefined>): void;
  /**
   * Return the project ID used by this class.
   * @returns {Promise} A promise that resolves to string containing the project ID.
   */
  getProjectId(
    callback?: Callback<string, undefined, undefined>,
  ): Promise<string> | void {
    if (callback) {
      this.auth.getProjectId(callback);
      return;
    }
    return this.auth.getProjectId();
  }

  // -------------------
  // -- Service calls --
  // -------------------
  /**
   * Gets the state of a Cloud Spanner database.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.name
   *   Required. The name of the requested database. Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.Database|Database}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  getDatabase(
    request?: protos.google.spanner.admin.database.v1.IGetDatabaseRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabase,
      protos.google.spanner.admin.database.v1.IGetDatabaseRequest | undefined,
      {} | undefined,
    ]
  >;
  getDatabase(
    request: protos.google.spanner.admin.database.v1.IGetDatabaseRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IDatabase,
      | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getDatabase(
    request: protos.google.spanner.admin.database.v1.IGetDatabaseRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IDatabase,
      | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getDatabase(
    request?: protos.google.spanner.admin.database.v1.IGetDatabaseRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IDatabase,
          | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IDatabase,
      | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabase,
      protos.google.spanner.admin.database.v1.IGetDatabaseRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('getDatabase request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IDatabase,
          | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('getDatabase response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .getDatabase(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IDatabase,
          (
            | protos.google.spanner.admin.database.v1.IGetDatabaseRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('getDatabase response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Drops (aka deletes) a Cloud Spanner database.
   * Completed backups for the database will be retained according to their
   * `expire_time`.
   * Note: Cloud Spanner might continue to accept requests for a few seconds
   * after the database has been deleted.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.database
   *   Required. The database to be dropped.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.protobuf.Empty|Empty}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  dropDatabase(
    request?: protos.google.spanner.admin.database.v1.IDropDatabaseRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      protos.google.spanner.admin.database.v1.IDropDatabaseRequest | undefined,
      {} | undefined,
    ]
  >;
  dropDatabase(
    request: protos.google.spanner.admin.database.v1.IDropDatabaseRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  dropDatabase(
    request: protos.google.spanner.admin.database.v1.IDropDatabaseRequest,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  dropDatabase(
    request?: protos.google.spanner.admin.database.v1.IDropDatabaseRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      protos.google.spanner.admin.database.v1.IDropDatabaseRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        database: request.database ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('dropDatabase request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('dropDatabase response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .dropDatabase(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.protobuf.IEmpty,
          (
            | protos.google.spanner.admin.database.v1.IDropDatabaseRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('dropDatabase response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Returns the schema of a Cloud Spanner database as a list of formatted
   * DDL statements. This method does not show pending schema updates, those may
   * be queried using the {@link protos.google.longrunning.Operations|Operations} API.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.database
   *   Required. The database whose schema we wish to get.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.GetDatabaseDdlResponse|GetDatabaseDdlResponse}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  getDatabaseDdl(
    request?: protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
      (
        | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  getDatabaseDdl(
    request: protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
      | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getDatabaseDdl(
    request: protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
      | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getDatabaseDdl(
    request?: protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
          | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
      | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
      (
        | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        database: request.database ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('getDatabaseDdl request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
          | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('getDatabaseDdl response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .getDatabaseDdl(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IGetDatabaseDdlResponse,
          (
            | protos.google.spanner.admin.database.v1.IGetDatabaseDdlRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('getDatabaseDdl response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Sets the access control policy on a database or backup resource.
   * Replaces any existing policy.
   *
   * Authorization requires `spanner.databases.setIamPolicy`
   * permission on {@link protos.google.iam.v1.SetIamPolicyRequest.resource|resource}.
   * For backups, authorization requires `spanner.backups.setIamPolicy`
   * permission on {@link protos.google.iam.v1.SetIamPolicyRequest.resource|resource}.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.resource
   *   REQUIRED: The resource for which the policy is being specified.
   *   See the operation documentation for the appropriate value for this field.
   * @param {google.iam.v1.Policy} request.policy
   *   REQUIRED: The complete policy to be applied to the `resource`. The size of
   *   the policy is limited to a few 10s of KB. An empty policy is a
   *   valid policy but certain Cloud Platform services (such as Projects)
   *   might reject them.
   * @param {google.protobuf.FieldMask} request.updateMask
   *   OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only
   *   the fields in the mask will be modified. If no mask is provided, the
   *   following default mask is used:
   *
   *   `paths: "bindings, etag"`
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.iam.v1.Policy|Policy}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  setIamPolicy(
    request?: protos.google.iam.v1.ISetIamPolicyRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.ISetIamPolicyRequest | undefined,
      {} | undefined,
    ]
  >;
  setIamPolicy(
    request: protos.google.iam.v1.ISetIamPolicyRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.ISetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  setIamPolicy(
    request: protos.google.iam.v1.ISetIamPolicyRequest,
    callback: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.ISetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  setIamPolicy(
    request?: protos.google.iam.v1.ISetIamPolicyRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.ISetIamPolicyRequest | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.ISetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.ISetIamPolicyRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        resource: request.resource ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('setIamPolicy request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.ISetIamPolicyRequest | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('setIamPolicy response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .setIamPolicy(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.ISetIamPolicyRequest | undefined,
          {} | undefined,
        ]) => {
          this._log.info('setIamPolicy response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Gets the access control policy for a database or backup resource.
   * Returns an empty policy if a database or backup exists but does not have a
   * policy set.
   *
   * Authorization requires `spanner.databases.getIamPolicy` permission on
   * {@link protos.google.iam.v1.GetIamPolicyRequest.resource|resource}.
   * For backups, authorization requires `spanner.backups.getIamPolicy`
   * permission on {@link protos.google.iam.v1.GetIamPolicyRequest.resource|resource}.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.resource
   *   REQUIRED: The resource for which the policy is being requested.
   *   See the operation documentation for the appropriate value for this field.
   * @param {google.iam.v1.GetPolicyOptions} request.options
   *   OPTIONAL: A `GetPolicyOptions` object for specifying options to
   *   `GetIamPolicy`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.iam.v1.Policy|Policy}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  getIamPolicy(
    request?: protos.google.iam.v1.IGetIamPolicyRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.IGetIamPolicyRequest | undefined,
      {} | undefined,
    ]
  >;
  getIamPolicy(
    request: protos.google.iam.v1.IGetIamPolicyRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.IGetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  getIamPolicy(
    request: protos.google.iam.v1.IGetIamPolicyRequest,
    callback: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.IGetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  getIamPolicy(
    request?: protos.google.iam.v1.IGetIamPolicyRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.IGetIamPolicyRequest | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.IGetIamPolicyRequest | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.iam.v1.IPolicy,
      protos.google.iam.v1.IGetIamPolicyRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        resource: request.resource ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('getIamPolicy request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.IGetIamPolicyRequest | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('getIamPolicy response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .getIamPolicy(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.iam.v1.IPolicy,
          protos.google.iam.v1.IGetIamPolicyRequest | undefined,
          {} | undefined,
        ]) => {
          this._log.info('getIamPolicy response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Returns permissions that the caller has on the specified database or backup
   * resource.
   *
   * Attempting this RPC on a non-existent Cloud Spanner database will
   * result in a NOT_FOUND error if the user has
   * `spanner.databases.list` permission on the containing Cloud
   * Spanner instance. Otherwise returns an empty set of permissions.
   * Calling this method on a backup that does not exist will
   * result in a NOT_FOUND error if the user has
   * `spanner.backups.list` permission on the containing instance.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.resource
   *   REQUIRED: The resource for which the policy detail is being requested.
   *   See the operation documentation for the appropriate value for this field.
   * @param {string[]} request.permissions
   *   The set of permissions to check for the `resource`. Permissions with
   *   wildcards (such as '*' or 'storage.*') are not allowed. For more
   *   information see
   *   [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions).
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.iam.v1.TestIamPermissionsResponse|TestIamPermissionsResponse}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  testIamPermissions(
    request?: protos.google.iam.v1.ITestIamPermissionsRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.iam.v1.ITestIamPermissionsResponse,
      protos.google.iam.v1.ITestIamPermissionsRequest | undefined,
      {} | undefined,
    ]
  >;
  testIamPermissions(
    request: protos.google.iam.v1.ITestIamPermissionsRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.iam.v1.ITestIamPermissionsResponse,
      protos.google.iam.v1.ITestIamPermissionsRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  testIamPermissions(
    request: protos.google.iam.v1.ITestIamPermissionsRequest,
    callback: Callback<
      protos.google.iam.v1.ITestIamPermissionsResponse,
      protos.google.iam.v1.ITestIamPermissionsRequest | null | undefined,
      {} | null | undefined
    >,
  ): void;
  testIamPermissions(
    request?: protos.google.iam.v1.ITestIamPermissionsRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.iam.v1.ITestIamPermissionsResponse,
          protos.google.iam.v1.ITestIamPermissionsRequest | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.iam.v1.ITestIamPermissionsResponse,
      protos.google.iam.v1.ITestIamPermissionsRequest | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.iam.v1.ITestIamPermissionsResponse,
      protos.google.iam.v1.ITestIamPermissionsRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        resource: request.resource ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('testIamPermissions request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.iam.v1.ITestIamPermissionsResponse,
          protos.google.iam.v1.ITestIamPermissionsRequest | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('testIamPermissions response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .testIamPermissions(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.iam.v1.ITestIamPermissionsResponse,
          protos.google.iam.v1.ITestIamPermissionsRequest | undefined,
          {} | undefined,
        ]) => {
          this._log.info('testIamPermissions response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Gets metadata on a pending or completed
   * {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.name
   *   Required. Name of the backup.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/backups/<backup>`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  getBackup(
    request?: protos.google.spanner.admin.database.v1.IGetBackupRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup,
      protos.google.spanner.admin.database.v1.IGetBackupRequest | undefined,
      {} | undefined,
    ]
  >;
  getBackup(
    request: protos.google.spanner.admin.database.v1.IGetBackupRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IGetBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getBackup(
    request: protos.google.spanner.admin.database.v1.IGetBackupRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IGetBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getBackup(
    request?: protos.google.spanner.admin.database.v1.IGetBackupRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IBackup,
          | protos.google.spanner.admin.database.v1.IGetBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IGetBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup,
      protos.google.spanner.admin.database.v1.IGetBackupRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('getBackup request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IBackup,
          | protos.google.spanner.admin.database.v1.IGetBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('getBackup response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .getBackup(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IBackup,
          protos.google.spanner.admin.database.v1.IGetBackupRequest | undefined,
          {} | undefined,
        ]) => {
          this._log.info('getBackup response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Updates a pending or completed
   * {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {google.spanner.admin.database.v1.Backup} request.backup
   *   Required. The backup to update. `backup.name`, and the fields to be updated
   *   as specified by `update_mask` are required. Other fields are ignored.
   *   Update is only supported for the following fields:
   *    * `backup.expire_time`.
   * @param {google.protobuf.FieldMask} request.updateMask
   *   Required. A mask specifying which fields (e.g. `expire_time`) in the
   *   Backup resource should be updated. This mask is relative to the Backup
   *   resource, not to the request message. The field mask must always be
   *   specified; this prevents any future fields from being erased accidentally
   *   by clients that do not know about them.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  updateBackup(
    request?: protos.google.spanner.admin.database.v1.IUpdateBackupRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup,
      protos.google.spanner.admin.database.v1.IUpdateBackupRequest | undefined,
      {} | undefined,
    ]
  >;
  updateBackup(
    request: protos.google.spanner.admin.database.v1.IUpdateBackupRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  updateBackup(
    request: protos.google.spanner.admin.database.v1.IUpdateBackupRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  updateBackup(
    request?: protos.google.spanner.admin.database.v1.IUpdateBackupRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IBackup,
          | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IBackup,
      | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup,
      protos.google.spanner.admin.database.v1.IUpdateBackupRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        'backup.name': request.backup!.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('updateBackup request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IBackup,
          | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('updateBackup response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .updateBackup(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IBackup,
          (
            | protos.google.spanner.admin.database.v1.IUpdateBackupRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('updateBackup response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Deletes a pending or completed
   * {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.name
   *   Required. Name of the backup to delete.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/backups/<backup>`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.protobuf.Empty|Empty}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  deleteBackup(
    request?: protos.google.spanner.admin.database.v1.IDeleteBackupRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      protos.google.spanner.admin.database.v1.IDeleteBackupRequest | undefined,
      {} | undefined,
    ]
  >;
  deleteBackup(
    request: protos.google.spanner.admin.database.v1.IDeleteBackupRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  deleteBackup(
    request: protos.google.spanner.admin.database.v1.IDeleteBackupRequest,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  deleteBackup(
    request?: protos.google.spanner.admin.database.v1.IDeleteBackupRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      protos.google.spanner.admin.database.v1.IDeleteBackupRequest | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('deleteBackup request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('deleteBackup response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .deleteBackup(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.protobuf.IEmpty,
          (
            | protos.google.spanner.admin.database.v1.IDeleteBackupRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('deleteBackup response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Adds split points to specified tables, indexes of a database.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.database
   *   Required. The database on whose tables/indexes split points are to be
   *   added. Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {number[]} request.splitPoints
   *   Required. The split points to add.
   * @param {string} [request.initiator]
   *   Optional. A user-supplied tag associated with the split points.
   *   For example, "intital_data_load", "special_event_1".
   *   Defaults to "CloudAddSplitPointsAPI" if not specified.
   *   The length of the tag must not exceed 50 characters,else will be trimmed.
   *   Only valid UTF8 characters are allowed.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.AddSplitPointsResponse|AddSplitPointsResponse}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  addSplitPoints(
    request?: protos.google.spanner.admin.database.v1.IAddSplitPointsRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
      (
        | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  addSplitPoints(
    request: protos.google.spanner.admin.database.v1.IAddSplitPointsRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
      | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  addSplitPoints(
    request: protos.google.spanner.admin.database.v1.IAddSplitPointsRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
      | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  addSplitPoints(
    request?: protos.google.spanner.admin.database.v1.IAddSplitPointsRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
          | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
      | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
      (
        | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        database: request.database ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('addSplitPoints request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
          | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('addSplitPoints response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .addSplitPoints(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IAddSplitPointsResponse,
          (
            | protos.google.spanner.admin.database.v1.IAddSplitPointsRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('addSplitPoints response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Creates a new backup schedule.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The name of the database that this backup schedule applies to.
   * @param {string} request.backupScheduleId
   *   Required. The Id to use for the backup schedule. The `backup_schedule_id`
   *   appended to `parent` forms the full backup schedule name of the form
   *   `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
   * @param {google.spanner.admin.database.v1.BackupSchedule} request.backupSchedule
   *   Required. The backup schedule to create.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  createBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  createBackupSchedule(
    request: protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  createBackupSchedule(
    request: protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  createBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('createBackupSchedule request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('createBackupSchedule response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .createBackupSchedule(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          (
            | protos.google.spanner.admin.database.v1.ICreateBackupScheduleRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('createBackupSchedule response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Gets backup schedule for the input schedule name.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.name
   *   Required. The name of the schedule to retrieve.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  getBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  getBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  getBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('getBackupSchedule request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('getBackupSchedule response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .getBackupSchedule(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          (
            | protos.google.spanner.admin.database.v1.IGetBackupScheduleRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('getBackupSchedule response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Updates a backup schedule.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {google.spanner.admin.database.v1.BackupSchedule} request.backupSchedule
   *   Required. The backup schedule to update. `backup_schedule.name`, and the
   *   fields to be updated as specified by `update_mask` are required. Other
   *   fields are ignored.
   * @param {google.protobuf.FieldMask} request.updateMask
   *   Required. A mask specifying which fields in the BackupSchedule resource
   *   should be updated. This mask is relative to the BackupSchedule resource,
   *   not to the request message. The field mask must always be
   *   specified; this prevents any future fields from being erased
   *   accidentally.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  updateBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  updateBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  updateBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  updateBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule,
      (
        | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        'backup_schedule.name': request.backupSchedule!.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('updateBackupSchedule request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('updateBackupSchedule response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .updateBackupSchedule(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IBackupSchedule,
          (
            | protos.google.spanner.admin.database.v1.IUpdateBackupScheduleRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('updateBackupSchedule response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * Deletes a backup schedule.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.name
   *   Required. The name of the schedule to delete.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>/backupSchedules/<backup_schedule_id>`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.protobuf.Empty|Empty}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  deleteBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      (
        | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  deleteBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  deleteBackupSchedule(
    request: protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest,
    callback: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  deleteBackupSchedule(
    request?: protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.protobuf.IEmpty,
      | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.protobuf.IEmpty,
      (
        | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('deleteBackupSchedule request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.protobuf.IEmpty,
          | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('deleteBackupSchedule response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .deleteBackupSchedule(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.protobuf.IEmpty,
          (
            | protos.google.spanner.admin.database.v1.IDeleteBackupScheduleRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('deleteBackupSchedule response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }
  /**
   * This is an internal API called by Spanner Graph jobs. You should never need
   * to call this API directly.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.database
   *   Internal field, do not use directly.
   * @param {string} request.operationId
   *   Internal field, do not use directly.
   * @param {string} request.vmIdentityToken
   *   Internal field, do not use directly.
   * @param {number} [request.progress]
   *   Internal field, do not use directly.
   * @param {google.rpc.Status} [request.status]
   *   Internal field, do not use directly.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing {@link protos.google.spanner.admin.database.v1.InternalUpdateGraphOperationResponse|InternalUpdateGraphOperationResponse}.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods | documentation }
   *   for more details and examples.
   */
  internalUpdateGraphOperation(
    request?: protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
      (
        | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
        | undefined
      ),
      {} | undefined,
    ]
  >;
  internalUpdateGraphOperation(
    request: protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest,
    options: CallOptions,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
      | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  internalUpdateGraphOperation(
    request: protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest,
    callback: Callback<
      protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
      | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): void;
  internalUpdateGraphOperation(
    request?: protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
          | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
          | null
          | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
      | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
      | null
      | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
      (
        | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
        | undefined
      ),
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('internalUpdateGraphOperation request %j', request);
    const wrappedCallback:
      | Callback<
          protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
          | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
          | null
          | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, options, rawResponse) => {
          this._log.info('internalUpdateGraphOperation response %j', response);
          callback!(error, response, options, rawResponse); // We verified callback above.
        }
      : undefined;
    return this.innerApiCalls
      .internalUpdateGraphOperation(request, options, wrappedCallback)
      ?.then(
        ([response, options, rawResponse]: [
          protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationResponse,
          (
            | protos.google.spanner.admin.database.v1.IInternalUpdateGraphOperationRequest
            | undefined
          ),
          {} | undefined,
        ]) => {
          this._log.info('internalUpdateGraphOperation response %j', response);
          return [response, options, rawResponse];
        },
      )
      .catch((error: any) => {
        if (
          error &&
          'statusDetails' in error &&
          error.statusDetails instanceof Array
        ) {
          const protos = this._gaxModule.protobuf.Root.fromJSON(
            jsonProtos,
          ) as unknown as gax.protobuf.Type;
          error.statusDetails = decodeAnyProtosInArray(
            error.statusDetails,
            protos,
          );
        }
        throw error;
      });
  }

  /**
   * Creates a new Cloud Spanner database and starts to prepare it for serving.
   * The returned {@link protos.google.longrunning.Operation|long-running operation} will
   * have a name of the format `<database_name>/operations/<operation_id>` and
   * can be used to track preparation of the database. The
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.CreateDatabaseMetadata|CreateDatabaseMetadata}.
   * The {@link protos.google.longrunning.Operation.response|response} field type is
   * {@link protos.google.spanner.admin.database.v1.Database|Database}, if successful.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The name of the instance that will serve the new database.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {string} request.createStatement
   *   Required. A `CREATE DATABASE` statement, which specifies the ID of the
   *   new database.  The database ID must conform to the regular expression
   *   `{@link protos.a-z0-9_\-|a-z}*[a-z0-9]` and be between 2 and 30 characters in length.
   *   If the database ID is a reserved word or if it contains a hyphen, the
   *   database ID must be enclosed in backticks (`` ` ``).
   * @param {string[]} [request.extraStatements]
   *   Optional. A list of DDL statements to run inside the newly created
   *   database. Statements can create tables, indexes, etc. These
   *   statements execute atomically with the creation of the database:
   *   if there is an error in any statement, the database is not created.
   * @param {google.spanner.admin.database.v1.EncryptionConfig} [request.encryptionConfig]
   *   Optional. The encryption configuration for the database. If this field is
   *   not specified, Cloud Spanner will encrypt/decrypt all data at rest using
   *   Google default encryption.
   * @param {google.spanner.admin.database.v1.DatabaseDialect} [request.databaseDialect]
   *   Optional. The dialect of the Cloud Spanner Database.
   * @param {Buffer} [request.protoDescriptors]
   *   Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements in
   *   'extra_statements' above.
   *   Contains a protobuf-serialized
   *   [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
   *   To generate it, [install](https://grpc.io/docs/protoc-installation/) and
   *   run `protoc` with --include_imports and --descriptor_set_out. For example,
   *   to generate for moon/shot/app.proto, run
   *   ```
   *   $protoc  --proto_path=/app_path --proto_path=/lib_path \
   *            --include_imports \
   *            --descriptor_set_out=descriptors.data \
   *            moon/shot/app.proto
   *   ```
   *   For more details, see protobuffer [self
   *   description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  createDatabase(
    request?: protos.google.spanner.admin.database.v1.ICreateDatabaseRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  createDatabase(
    request: protos.google.spanner.admin.database.v1.ICreateDatabaseRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  createDatabase(
    request: protos.google.spanner.admin.database.v1.ICreateDatabaseRequest,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  createDatabase(
    request?: protos.google.spanner.admin.database.v1.ICreateDatabaseRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('createDatabase response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('createDatabase request %j', request);
    return this.innerApiCalls
      .createDatabase(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.ICreateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('createDatabase response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `createDatabase()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkCreateDatabaseProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.CreateDatabaseMetadata
    >
  > {
    this._log.info('createDatabase long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.createDatabase,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.CreateDatabaseMetadata
    >;
  }
  /**
   * Updates a Cloud Spanner database. The returned
   * {@link protos.google.longrunning.Operation|long-running operation} can be used to track
   * the progress of updating the database. If the named database does not
   * exist, returns `NOT_FOUND`.
   *
   * While the operation is pending:
   *
   *   * The database's
   *     {@link protos.google.spanner.admin.database.v1.Database.reconciling|reconciling}
   *     field is set to true.
   *   * Cancelling the operation is best-effort. If the cancellation succeeds,
   *     the operation metadata's
   *     {@link protos.google.spanner.admin.database.v1.UpdateDatabaseMetadata.cancel_time|cancel_time}
   *     is set, the updates are reverted, and the operation terminates with a
   *     `CANCELLED` status.
   *   * New UpdateDatabase requests will return a `FAILED_PRECONDITION` error
   *     until the pending operation is done (returns successfully or with
   *     error).
   *   * Reading the database via the API continues to give the pre-request
   *     values.
   *
   * Upon completion of the returned operation:
   *
   *   * The new values are in effect and readable via the API.
   *   * The database's
   *     {@link protos.google.spanner.admin.database.v1.Database.reconciling|reconciling}
   *     field becomes false.
   *
   * The returned {@link protos.google.longrunning.Operation|long-running operation} will
   * have a name of the format
   * `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>`
   * and can be used to track the database modification. The
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.UpdateDatabaseMetadata|UpdateDatabaseMetadata}.
   * The {@link protos.google.longrunning.Operation.response|response} field type is
   * {@link protos.google.spanner.admin.database.v1.Database|Database}, if successful.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {google.spanner.admin.database.v1.Database} request.database
   *   Required. The database to update.
   *   The `name` field of the database is of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {google.protobuf.FieldMask} request.updateMask
   *   Required. The list of fields to update. Currently, only
   *   `enable_drop_protection` field can be updated.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  updateDatabase(
    request?: protos.google.spanner.admin.database.v1.IUpdateDatabaseRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  updateDatabase(
    request: protos.google.spanner.admin.database.v1.IUpdateDatabaseRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  updateDatabase(
    request: protos.google.spanner.admin.database.v1.IUpdateDatabaseRequest,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  updateDatabase(
    request?: protos.google.spanner.admin.database.v1.IUpdateDatabaseRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        'database.name': request.database!.name ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('updateDatabase response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('updateDatabase request %j', request);
    return this.innerApiCalls
      .updateDatabase(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('updateDatabase response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `updateDatabase()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkUpdateDatabaseProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.UpdateDatabaseMetadata
    >
  > {
    this._log.info('updateDatabase long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.updateDatabase,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.UpdateDatabaseMetadata
    >;
  }
  /**
   * Updates the schema of a Cloud Spanner database by
   * creating/altering/dropping tables, columns, indexes, etc. The returned
   * {@link protos.google.longrunning.Operation|long-running operation} will have a name of
   * the format `<database_name>/operations/<operation_id>` and can be used to
   * track execution of the schema change(s). The
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata|UpdateDatabaseDdlMetadata}.
   * The operation has no response.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.database
   *   Required. The database to update.
   * @param {string[]} request.statements
   *   Required. DDL statements to be applied to the database.
   * @param {string} request.operationId
   *   If empty, the new update request is assigned an
   *   automatically-generated operation ID. Otherwise, `operation_id`
   *   is used to construct the name of the resulting
   *   {@link protos.google.longrunning.Operation|Operation}.
   *
   *   Specifying an explicit operation ID simplifies determining
   *   whether the statements were executed in the event that the
   *   {@link protos.google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl|UpdateDatabaseDdl}
   *   call is replayed, or the return value is otherwise lost: the
   *   {@link protos.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.database|database}
   *   and `operation_id` fields can be combined to form the
   *   {@link protos.google.longrunning.Operation.name|name} of the resulting
   *   {@link protos.google.longrunning.Operation|longrunning.Operation}:
   *   `<database>/operations/<operation_id>`.
   *
   *   `operation_id` should be unique within the database, and must be
   *   a valid identifier: `{@link protos.a-z0-9_|a-z}*`. Note that
   *   automatically-generated operation IDs always begin with an
   *   underscore. If the named operation already exists,
   *   {@link protos.google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl|UpdateDatabaseDdl}
   *   returns `ALREADY_EXISTS`.
   * @param {Buffer} [request.protoDescriptors]
   *   Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements.
   *   Contains a protobuf-serialized
   *   [google.protobuf.FileDescriptorSet](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto).
   *   To generate it, [install](https://grpc.io/docs/protoc-installation/) and
   *   run `protoc` with --include_imports and --descriptor_set_out. For example,
   *   to generate for moon/shot/app.proto, run
   *   ```
   *   $protoc  --proto_path=/app_path --proto_path=/lib_path \
   *            --include_imports \
   *            --descriptor_set_out=descriptors.data \
   *            moon/shot/app.proto
   *   ```
   *   For more details, see protobuffer [self
   *   description](https://developers.google.com/protocol-buffers/docs/techniques#self-description).
   * @param {boolean} [request.throughputMode]
   *   Optional. This field is exposed to be used by the Spanner Migration Tool.
   *   For more details, see
   *   [SMT](https://github.com/GoogleCloudPlatform/spanner-migration-tool).
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  updateDatabaseDdl(
    request?: protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.protobuf.IEmpty,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  updateDatabaseDdl(
    request: protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.protobuf.IEmpty,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  updateDatabaseDdl(
    request: protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlRequest,
    callback: Callback<
      LROperation<
        protos.google.protobuf.IEmpty,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  updateDatabaseDdl(
    request?: protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.protobuf.IEmpty,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.protobuf.IEmpty,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.protobuf.IEmpty,
        protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        database: request.database ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.protobuf.IEmpty,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('updateDatabaseDdl response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('updateDatabaseDdl request %j', request);
    return this.innerApiCalls
      .updateDatabaseDdl(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.protobuf.IEmpty,
            protos.google.spanner.admin.database.v1.IUpdateDatabaseDdlMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('updateDatabaseDdl response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `updateDatabaseDdl()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkUpdateDatabaseDdlProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.protobuf.Empty,
      protos.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata
    >
  > {
    this._log.info('updateDatabaseDdl long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.updateDatabaseDdl,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.protobuf.Empty,
      protos.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata
    >;
  }
  /**
   * Starts creating a new Cloud Spanner Backup.
   * The returned backup {@link protos.google.longrunning.Operation|long-running operation}
   * will have a name of the format
   * `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>`
   * and can be used to track creation of the backup. The
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   * The {@link protos.google.longrunning.Operation.response|response} field type is
   * {@link protos.google.spanner.admin.database.v1.Backup|Backup}, if successful.
   * Cancelling the returned operation will stop the creation and delete the
   * backup. There can be only one pending backup creation per database. Backup
   * creation of different databases can run concurrently.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The name of the instance in which the backup will be
   *   created. This must be the same instance that contains the database the
   *   backup will be created from. The backup will be stored in the
   *   location(s) specified in the instance configuration of this
   *   instance. Values are of the form
   *   `projects/<project>/instances/<instance>`.
   * @param {string} request.backupId
   *   Required. The id of the backup to be created. The `backup_id` appended to
   *   `parent` forms the full backup name of the form
   *   `projects/<project>/instances/<instance>/backups/<backup_id>`.
   * @param {google.spanner.admin.database.v1.Backup} request.backup
   *   Required. The backup to create.
   * @param {google.spanner.admin.database.v1.CreateBackupEncryptionConfig} [request.encryptionConfig]
   *   Optional. The encryption configuration used to encrypt the backup. If this
   *   field is not specified, the backup will use the same encryption
   *   configuration as the database by default, namely
   *   {@link protos.google.spanner.admin.database.v1.CreateBackupEncryptionConfig.encryption_type|encryption_type}
   *   = `USE_DATABASE_ENCRYPTION`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  createBackup(
    request?: protos.google.spanner.admin.database.v1.ICreateBackupRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICreateBackupMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  createBackup(
    request: protos.google.spanner.admin.database.v1.ICreateBackupRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICreateBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  createBackup(
    request: protos.google.spanner.admin.database.v1.ICreateBackupRequest,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICreateBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  createBackup(
    request?: protos.google.spanner.admin.database.v1.ICreateBackupRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICreateBackupMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICreateBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICreateBackupMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICreateBackupMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('createBackup response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('createBackup request %j', request);
    return this.innerApiCalls
      .createBackup(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICreateBackupMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('createBackup response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `createBackup()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkCreateBackupProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.spanner.admin.database.v1.Backup,
      protos.google.spanner.admin.database.v1.CreateBackupMetadata
    >
  > {
    this._log.info('createBackup long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.createBackup,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.spanner.admin.database.v1.Backup,
      protos.google.spanner.admin.database.v1.CreateBackupMetadata
    >;
  }
  /**
   * Starts copying a Cloud Spanner Backup.
   * The returned backup {@link protos.google.longrunning.Operation|long-running operation}
   * will have a name of the format
   * `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>`
   * and can be used to track copying of the backup. The operation is associated
   * with the destination backup.
   * The {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}.
   * The {@link protos.google.longrunning.Operation.response|response} field type is
   * {@link protos.google.spanner.admin.database.v1.Backup|Backup}, if successful.
   * Cancelling the returned operation will stop the copying and delete the
   * destination backup. Concurrent CopyBackup requests can run on the same
   * source backup.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The name of the destination instance that will contain the backup
   *   copy. Values are of the form: `projects/<project>/instances/<instance>`.
   * @param {string} request.backupId
   *   Required. The id of the backup copy.
   *   The `backup_id` appended to `parent` forms the full backup_uri of the form
   *   `projects/<project>/instances/<instance>/backups/<backup>`.
   * @param {string} request.sourceBackup
   *   Required. The source backup to be copied.
   *   The source backup needs to be in READY state for it to be copied.
   *   Once CopyBackup is in progress, the source backup cannot be deleted or
   *   cleaned up on expiration until CopyBackup is finished.
   *   Values are of the form:
   *   `projects/<project>/instances/<instance>/backups/<backup>`.
   * @param {google.protobuf.Timestamp} request.expireTime
   *   Required. The expiration time of the backup in microsecond granularity.
   *   The expiration time must be at least 6 hours and at most 366 days
   *   from the `create_time` of the source backup. Once the `expire_time` has
   *   passed, the backup is eligible to be automatically deleted by Cloud Spanner
   *   to free the resources used by the backup.
   * @param {google.spanner.admin.database.v1.CopyBackupEncryptionConfig} [request.encryptionConfig]
   *   Optional. The encryption configuration used to encrypt the backup. If this
   *   field is not specified, the backup will use the same encryption
   *   configuration as the source backup by default, namely
   *   {@link protos.google.spanner.admin.database.v1.CopyBackupEncryptionConfig.encryption_type|encryption_type}
   *   = `USE_CONFIG_DEFAULT_OR_BACKUP_ENCRYPTION`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  copyBackup(
    request?: protos.google.spanner.admin.database.v1.ICopyBackupRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICopyBackupMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  copyBackup(
    request: protos.google.spanner.admin.database.v1.ICopyBackupRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICopyBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  copyBackup(
    request: protos.google.spanner.admin.database.v1.ICopyBackupRequest,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICopyBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  copyBackup(
    request?: protos.google.spanner.admin.database.v1.ICopyBackupRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICopyBackupMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICopyBackupMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IBackup,
        protos.google.spanner.admin.database.v1.ICopyBackupMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICopyBackupMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('copyBackup response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('copyBackup request %j', request);
    return this.innerApiCalls
      .copyBackup(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.spanner.admin.database.v1.IBackup,
            protos.google.spanner.admin.database.v1.ICopyBackupMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('copyBackup response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `copyBackup()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkCopyBackupProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.spanner.admin.database.v1.Backup,
      protos.google.spanner.admin.database.v1.CopyBackupMetadata
    >
  > {
    this._log.info('copyBackup long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.copyBackup,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.spanner.admin.database.v1.Backup,
      protos.google.spanner.admin.database.v1.CopyBackupMetadata
    >;
  }
  /**
   * Create a new database by restoring from a completed backup. The new
   * database must be in the same project and in an instance with the same
   * instance configuration as the instance containing
   * the backup. The returned database [long-running
   * operation][google.longrunning.Operation] has a name of the format
   * `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>`,
   * and can be used to track the progress of the operation, and to cancel it.
   * The {@link protos.google.longrunning.Operation.metadata|metadata} field type is
   * {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}.
   * The {@link protos.google.longrunning.Operation.response|response} type
   * is {@link protos.google.spanner.admin.database.v1.Database|Database}, if
   * successful. Cancelling the returned operation will stop the restore and
   * delete the database.
   * There can be only one database being restored into an instance at a time.
   * Once the restore operation completes, a new restore operation can be
   * initiated, without waiting for the optimize operation associated with the
   * first restore to complete.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The name of the instance in which to create the
   *   restored database. This instance must be in the same project and
   *   have the same instance configuration as the instance containing
   *   the source backup. Values are of the form
   *   `projects/<project>/instances/<instance>`.
   * @param {string} request.databaseId
   *   Required. The id of the database to create and restore to. This
   *   database must not already exist. The `database_id` appended to
   *   `parent` forms the full database name of the form
   *   `projects/<project>/instances/<instance>/databases/<database_id>`.
   * @param {string} request.backup
   *   Name of the backup from which to restore.  Values are of the form
   *   `projects/<project>/instances/<instance>/backups/<backup>`.
   * @param {google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig} [request.encryptionConfig]
   *   Optional. An encryption configuration describing the encryption type and
   *   key resources in Cloud KMS used to encrypt/decrypt the database to restore
   *   to. If this field is not specified, the restored database will use the same
   *   encryption configuration as the backup by default, namely
   *   {@link protos.google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig.encryption_type|encryption_type}
   *   = `USE_CONFIG_DEFAULT_OR_BACKUP_ENCRYPTION`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   *   a long running operation. Its `promise()` method returns a promise
   *   you can `await` for.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  restoreDatabase(
    request?: protos.google.spanner.admin.database.v1.IRestoreDatabaseRequest,
    options?: CallOptions,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  >;
  restoreDatabase(
    request: protos.google.spanner.admin.database.v1.IRestoreDatabaseRequest,
    options: CallOptions,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  restoreDatabase(
    request: protos.google.spanner.admin.database.v1.IRestoreDatabaseRequest,
    callback: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): void;
  restoreDatabase(
    request?: protos.google.spanner.admin.database.v1.IRestoreDatabaseRequest,
    optionsOrCallback?:
      | CallOptions
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >,
    callback?: Callback<
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | null | undefined,
      {} | null | undefined
    >,
  ): Promise<
    [
      LROperation<
        protos.google.spanner.admin.database.v1.IDatabase,
        protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
      >,
      protos.google.longrunning.IOperation | undefined,
      {} | undefined,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | Callback<
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | null | undefined,
          {} | null | undefined
        >
      | undefined = callback
      ? (error, response, rawResponse, _) => {
          this._log.info('restoreDatabase response %j', rawResponse);
          callback!(error, response, rawResponse, _); // We verified callback above.
        }
      : undefined;
    this._log.info('restoreDatabase request %j', request);
    return this.innerApiCalls
      .restoreDatabase(request, options, wrappedCallback)
      ?.then(
        ([response, rawResponse, _]: [
          LROperation<
            protos.google.spanner.admin.database.v1.IDatabase,
            protos.google.spanner.admin.database.v1.IRestoreDatabaseMetadata
          >,
          protos.google.longrunning.IOperation | undefined,
          {} | undefined,
        ]) => {
          this._log.info('restoreDatabase response %j', rawResponse);
          return [response, rawResponse, _];
        },
      );
  }
  /**
   * Check the status of the long running operation returned by `restoreDatabase()`.
   * @param {String} name
   *   The operation name that will be passed.
   * @returns {Promise} - The promise which resolves to an object.
   *   The decoded operation object has result and metadata field to get information from.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#long-running-operations | documentation }
   *   for more details and examples.
   */
  async checkRestoreDatabaseProgress(
    name: string,
  ): Promise<
    LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata
    >
  > {
    this._log.info('restoreDatabase long-running');
    const request =
      new this._gaxModule.operationsProtos.google.longrunning.GetOperationRequest(
        {name},
      );
    const [operation] = await this.operationsClient.getOperation(request);
    const decodeOperation = new this._gaxModule.Operation(
      operation,
      this.descriptors.longrunning.restoreDatabase,
      this._gaxModule.createDefaultBackoffSettings(),
    );
    return decodeOperation as LROperation<
      protos.google.spanner.admin.database.v1.Database,
      protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata
    >;
  }
  /**
   * Lists Cloud Spanner databases.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance whose databases should be listed.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {number} request.pageSize
   *   Number of databases to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse|ListDatabasesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.spanner.admin.database.v1.Database|Database}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listDatabasesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabases(
    request?: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabase[],
      protos.google.spanner.admin.database.v1.IListDatabasesRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabasesResponse,
    ]
  >;
  listDatabases(
    request: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabasesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabasesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabase
    >,
  ): void;
  listDatabases(
    request: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabasesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabasesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabase
    >,
  ): void;
  listDatabases(
    request?: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabasesRequest,
          | protos.google.spanner.admin.database.v1.IListDatabasesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IDatabase
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabasesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabasesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabase
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabase[],
      protos.google.spanner.admin.database.v1.IListDatabasesRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabasesResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabasesRequest,
          | protos.google.spanner.admin.database.v1.IListDatabasesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IDatabase
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listDatabases values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listDatabases request %j', request);
    return this.innerApiCalls
      .listDatabases(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.spanner.admin.database.v1.IDatabase[],
          protos.google.spanner.admin.database.v1.IListDatabasesRequest | null,
          protos.google.spanner.admin.database.v1.IListDatabasesResponse,
        ]) => {
          this._log.info('listDatabases values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listDatabases`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance whose databases should be listed.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {number} request.pageSize
   *   Number of databases to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse|ListDatabasesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.spanner.admin.database.v1.Database|Database} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listDatabasesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabasesStream(
    request?: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabases'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabases stream %j', request);
    return this.descriptors.page.listDatabases.createStream(
      this.innerApiCalls.listDatabases as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listDatabases`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance whose databases should be listed.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {number} request.pageSize
   *   Number of databases to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabasesResponse|ListDatabasesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.spanner.admin.database.v1.Database|Database}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabasesAsync(
    request?: protos.google.spanner.admin.database.v1.IListDatabasesRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.spanner.admin.database.v1.IDatabase> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabases'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabases iterate %j', request);
    return this.descriptors.page.listDatabases.asyncIterate(
      this.innerApiCalls['listDatabases'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.spanner.admin.database.v1.IDatabase>;
  }
  /**
   * Lists completed and pending backups.
   * Backups returned are ordered by `create_time` in descending order,
   * starting from the most recent `create_time`.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance to list backups from.  Values are of the
   *   form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backups.
   *
   *   A filter expression consists of a field name, a comparison operator, and a
   *   value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the
   *   {@link protos.google.spanner.admin.database.v1.Backup|Backup} are eligible for
   *   filtering:
   *
   *     * `name`
   *     * `database`
   *     * `state`
   *     * `create_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `expire_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `version_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `size_bytes`
   *     * `backup_schedules`
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `name:Howl` - The backup's name contains the string "howl".
   *     * `database:prod`
   *            - The database's name contains the string "prod".
   *     * `state:CREATING` - The backup is pending creation.
   *     * `state:READY` - The backup is fully created and ready for use.
   *     * `(name:howl) AND (create_time < \"2018-03-28T14:50:00Z\")`
   *            - The backup name contains the string "howl" and `create_time`
   *                of the backup is before 2018-03-28T14:50:00Z.
   *     * `expire_time < \"2018-03-28T14:50:00Z\"`
   *            - The backup `expire_time` is before 2018-03-28T14:50:00Z.
   *     * `size_bytes > 10000000000` - The backup's size is greater than 10GB
   *     * `backup_schedules:daily`
   *            - The backup is created from a schedule with "daily" in its name.
   * @param {number} request.pageSize
   *   Number of backups to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse|ListBackupsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.spanner.admin.database.v1.Backup|Backup}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listBackupsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackups(
    request?: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup[],
      protos.google.spanner.admin.database.v1.IListBackupsRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupsResponse,
    ]
  >;
  listBackups(
    request: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupsResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackup
    >,
  ): void;
  listBackups(
    request: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupsResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackup
    >,
  ): void;
  listBackups(
    request?: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupsRequest,
          | protos.google.spanner.admin.database.v1.IListBackupsResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IBackup
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupsResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackup
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackup[],
      protos.google.spanner.admin.database.v1.IListBackupsRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupsResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupsRequest,
          | protos.google.spanner.admin.database.v1.IListBackupsResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IBackup
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listBackups values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listBackups request %j', request);
    return this.innerApiCalls
      .listBackups(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.spanner.admin.database.v1.IBackup[],
          protos.google.spanner.admin.database.v1.IListBackupsRequest | null,
          protos.google.spanner.admin.database.v1.IListBackupsResponse,
        ]) => {
          this._log.info('listBackups values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listBackups`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance to list backups from.  Values are of the
   *   form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backups.
   *
   *   A filter expression consists of a field name, a comparison operator, and a
   *   value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the
   *   {@link protos.google.spanner.admin.database.v1.Backup|Backup} are eligible for
   *   filtering:
   *
   *     * `name`
   *     * `database`
   *     * `state`
   *     * `create_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `expire_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `version_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `size_bytes`
   *     * `backup_schedules`
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `name:Howl` - The backup's name contains the string "howl".
   *     * `database:prod`
   *            - The database's name contains the string "prod".
   *     * `state:CREATING` - The backup is pending creation.
   *     * `state:READY` - The backup is fully created and ready for use.
   *     * `(name:howl) AND (create_time < \"2018-03-28T14:50:00Z\")`
   *            - The backup name contains the string "howl" and `create_time`
   *                of the backup is before 2018-03-28T14:50:00Z.
   *     * `expire_time < \"2018-03-28T14:50:00Z\"`
   *            - The backup `expire_time` is before 2018-03-28T14:50:00Z.
   *     * `size_bytes > 10000000000` - The backup's size is greater than 10GB
   *     * `backup_schedules:daily`
   *            - The backup is created from a schedule with "daily" in its name.
   * @param {number} request.pageSize
   *   Number of backups to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse|ListBackupsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.spanner.admin.database.v1.Backup|Backup} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listBackupsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupsStream(
    request?: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackups'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackups stream %j', request);
    return this.descriptors.page.listBackups.createStream(
      this.innerApiCalls.listBackups as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listBackups`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance to list backups from.  Values are of the
   *   form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backups.
   *
   *   A filter expression consists of a field name, a comparison operator, and a
   *   value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the
   *   {@link protos.google.spanner.admin.database.v1.Backup|Backup} are eligible for
   *   filtering:
   *
   *     * `name`
   *     * `database`
   *     * `state`
   *     * `create_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `expire_time`  (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `version_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ)
   *     * `size_bytes`
   *     * `backup_schedules`
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `name:Howl` - The backup's name contains the string "howl".
   *     * `database:prod`
   *            - The database's name contains the string "prod".
   *     * `state:CREATING` - The backup is pending creation.
   *     * `state:READY` - The backup is fully created and ready for use.
   *     * `(name:howl) AND (create_time < \"2018-03-28T14:50:00Z\")`
   *            - The backup name contains the string "howl" and `create_time`
   *                of the backup is before 2018-03-28T14:50:00Z.
   *     * `expire_time < \"2018-03-28T14:50:00Z\"`
   *            - The backup `expire_time` is before 2018-03-28T14:50:00Z.
   *     * `size_bytes > 10000000000` - The backup's size is greater than 10GB
   *     * `backup_schedules:daily`
   *            - The backup is created from a schedule with "daily" in its name.
   * @param {number} request.pageSize
   *   Number of backups to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupsResponse|ListBackupsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.spanner.admin.database.v1.Backup|Backup}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupsAsync(
    request?: protos.google.spanner.admin.database.v1.IListBackupsRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.spanner.admin.database.v1.IBackup> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackups'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackups iterate %j', request);
    return this.descriptors.page.listBackups.asyncIterate(
      this.innerApiCalls['listBackups'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.spanner.admin.database.v1.IBackup>;
  }
  /**
   * Lists database {@link protos.google.longrunning.Operation|longrunning-operations}.
   * A database operation has a name of the form
   * `projects/<project>/instances/<instance>/databases/<database>/operations/<operation>`.
   * The long-running operation
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type
   * `metadata.type_url` describes the type of the metadata. Operations returned
   * include those that have completed/failed/canceled within the last 7 days,
   * and pending operations.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the database operations.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|Operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first, if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic. However,
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata) AND` \
   *       `(metadata.source_type:BACKUP) AND` \
   *       `(metadata.backup_info.backup:backup_howl) AND` \
   *       `(metadata.name:restored_howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Return operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}.
   *       * The database is restored from a backup.
   *       * The backup name contains "backup_howl".
   *       * The restored database's name contains "restored_howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse|ListDatabaseOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.longrunning.Operation|Operation}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listDatabaseOperationsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseOperations(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.longrunning.IOperation[],
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse,
    ]
  >;
  listDatabaseOperations(
    request: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): void;
  listDatabaseOperations(
    request: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): void;
  listDatabaseOperations(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
          | protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse
          | null
          | undefined,
          protos.google.longrunning.IOperation
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): Promise<
    [
      protos.google.longrunning.IOperation[],
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
          | protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse
          | null
          | undefined,
          protos.google.longrunning.IOperation
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listDatabaseOperations values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listDatabaseOperations request %j', request);
    return this.innerApiCalls
      .listDatabaseOperations(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.longrunning.IOperation[],
          protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest | null,
          protos.google.spanner.admin.database.v1.IListDatabaseOperationsResponse,
        ]) => {
          this._log.info('listDatabaseOperations values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listDatabaseOperations`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the database operations.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|Operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first, if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic. However,
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata) AND` \
   *       `(metadata.source_type:BACKUP) AND` \
   *       `(metadata.backup_info.backup:backup_howl) AND` \
   *       `(metadata.name:restored_howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Return operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}.
   *       * The database is restored from a backup.
   *       * The backup name contains "backup_howl".
   *       * The restored database's name contains "restored_howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse|ListDatabaseOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.longrunning.Operation|Operation} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listDatabaseOperationsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseOperationsStream(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabaseOperations'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabaseOperations stream %j', request);
    return this.descriptors.page.listDatabaseOperations.createStream(
      this.innerApiCalls.listDatabaseOperations as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listDatabaseOperations`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the database operations.
   *   Values are of the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|Operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first, if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic. However,
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata) AND` \
   *       `(metadata.source_type:BACKUP) AND` \
   *       `(metadata.backup_info.backup:backup_howl) AND` \
   *       `(metadata.name:restored_howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Return operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.RestoreDatabaseMetadata|RestoreDatabaseMetadata}.
   *       * The database is restored from a backup.
   *       * The backup name contains "backup_howl".
   *       * The restored database's name contains "restored_howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseOperationsResponse|ListDatabaseOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.longrunning.Operation|Operation}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseOperationsAsync(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseOperationsRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.longrunning.IOperation> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabaseOperations'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabaseOperations iterate %j', request);
    return this.descriptors.page.listDatabaseOperations.asyncIterate(
      this.innerApiCalls['listDatabaseOperations'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.longrunning.IOperation>;
  }
  /**
   * Lists the backup {@link protos.google.longrunning.Operation|long-running operations} in
   * the given instance. A backup operation has a name of the form
   * `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation>`.
   * The long-running operation
   * {@link protos.google.longrunning.Operation.metadata|metadata} field type
   * `metadata.type_url` describes the type of the metadata. Operations returned
   * include those that have completed/failed/canceled within the last 7 days,
   * and pending operations. Operations returned are ordered by
   * `operation.metadata.value.progress.start_time` in descending order starting
   * from the most recently started operation.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the backup operations. Values are of
   *   the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backup operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *        `metadata.database:prod` - Returns operations where:
   *        * The operation's metadata type is
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *        * The source database name of backup contains the string "prod".
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.name:howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *       * The backup name contains the string "howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND` \
   *       `(metadata.source_backup:test) AND` \
   *       `(metadata.progress.start_time < \"2022-01-18T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}.
   *       * The source backup name contains the string "test".
   *       * The operation started before 2022-01-18T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.database:test_db)) OR` \
   *       `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata)
   *       AND` \
   *       `(metadata.source_backup:test_bkp)) AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata matches either of criteria:
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *         AND the source database name of the backup contains the string
   *         "test_db"
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}
   *         AND the source backup name contains the string "test_bkp"
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse|ListBackupOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.longrunning.Operation|Operation}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listBackupOperationsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupOperations(
    request?: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.longrunning.IOperation[],
      protos.google.spanner.admin.database.v1.IListBackupOperationsRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupOperationsResponse,
    ]
  >;
  listBackupOperations(
    request: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): void;
  listBackupOperations(
    request: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): void;
  listBackupOperations(
    request?: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
          | protos.google.spanner.admin.database.v1.IListBackupOperationsResponse
          | null
          | undefined,
          protos.google.longrunning.IOperation
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
      | protos.google.spanner.admin.database.v1.IListBackupOperationsResponse
      | null
      | undefined,
      protos.google.longrunning.IOperation
    >,
  ): Promise<
    [
      protos.google.longrunning.IOperation[],
      protos.google.spanner.admin.database.v1.IListBackupOperationsRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupOperationsResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
          | protos.google.spanner.admin.database.v1.IListBackupOperationsResponse
          | null
          | undefined,
          protos.google.longrunning.IOperation
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listBackupOperations values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listBackupOperations request %j', request);
    return this.innerApiCalls
      .listBackupOperations(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.longrunning.IOperation[],
          protos.google.spanner.admin.database.v1.IListBackupOperationsRequest | null,
          protos.google.spanner.admin.database.v1.IListBackupOperationsResponse,
        ]) => {
          this._log.info('listBackupOperations values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listBackupOperations`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the backup operations. Values are of
   *   the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backup operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *        `metadata.database:prod` - Returns operations where:
   *        * The operation's metadata type is
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *        * The source database name of backup contains the string "prod".
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.name:howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *       * The backup name contains the string "howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND` \
   *       `(metadata.source_backup:test) AND` \
   *       `(metadata.progress.start_time < \"2022-01-18T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}.
   *       * The source backup name contains the string "test".
   *       * The operation started before 2022-01-18T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.database:test_db)) OR` \
   *       `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata)
   *       AND` \
   *       `(metadata.source_backup:test_bkp)) AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata matches either of criteria:
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *         AND the source database name of the backup contains the string
   *         "test_db"
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}
   *         AND the source backup name contains the string "test_bkp"
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse|ListBackupOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.longrunning.Operation|Operation} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listBackupOperationsAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupOperationsStream(
    request?: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackupOperations'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackupOperations stream %j', request);
    return this.descriptors.page.listBackupOperations.createStream(
      this.innerApiCalls.listBackupOperations as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listBackupOperations`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The instance of the backup operations. Values are of
   *   the form `projects/<project>/instances/<instance>`.
   * @param {string} request.filter
   *   An expression that filters the list of returned backup operations.
   *
   *   A filter expression consists of a field name, a
   *   comparison operator, and a value for filtering.
   *   The value must be a string, a number, or a boolean. The comparison operator
   *   must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
   *   Colon `:` is the contains operator. Filter rules are not case sensitive.
   *
   *   The following fields in the {@link protos.google.longrunning.Operation|operation}
   *   are eligible for filtering:
   *
   *     * `name` - The name of the long-running operation
   *     * `done` - False if the operation is in progress, else true.
   *     * `metadata.@type` - the type of metadata. For example, the type string
   *        for
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *        is
   *        `type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata`.
   *     * `metadata.<field_name>` - any field in metadata.value.
   *        `metadata.@type` must be specified first if filtering on metadata
   *        fields.
   *     * `error` - Error associated with the long-running operation.
   *     * `response.@type` - the type of response.
   *     * `response.<field_name>` - any field in response.value.
   *
   *   You can combine multiple expressions by enclosing each expression in
   *   parentheses. By default, expressions are combined with AND logic, but
   *   you can specify AND, OR, and NOT logic explicitly.
   *
   *   Here are a few examples:
   *
   *     * `done:true` - The operation is complete.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *        `metadata.database:prod` - Returns operations where:
   *        * The operation's metadata type is
   *        {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *        * The source database name of backup contains the string "prod".
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.name:howl) AND` \
   *       `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}.
   *       * The backup name contains the string "howl".
   *       * The operation started before 2018-03-28T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata) AND` \
   *       `(metadata.source_backup:test) AND` \
   *       `(metadata.progress.start_time < \"2022-01-18T14:50:00Z\") AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata type is
   *       {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}.
   *       * The source backup name contains the string "test".
   *       * The operation started before 2022-01-18T14:50:00Z.
   *       * The operation resulted in an error.
   *     * `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CreateBackupMetadata) AND` \
   *       `(metadata.database:test_db)) OR` \
   *       `((metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.CopyBackupMetadata)
   *       AND` \
   *       `(metadata.source_backup:test_bkp)) AND` \
   *       `(error:*)` - Returns operations where:
   *       * The operation's metadata matches either of criteria:
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CreateBackupMetadata|CreateBackupMetadata}
   *         AND the source database name of the backup contains the string
   *         "test_db"
   *         * The operation's metadata type is
   *         {@link protos.google.spanner.admin.database.v1.CopyBackupMetadata|CopyBackupMetadata}
   *         AND the source backup name contains the string "test_bkp"
   *       * The operation resulted in an error.
   * @param {number} request.pageSize
   *   Number of operations to be returned in the response. If 0 or
   *   less, defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupOperationsResponse|ListBackupOperationsResponse}
   *   to the same `parent` and with the same `filter`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.longrunning.Operation|Operation}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupOperationsAsync(
    request?: protos.google.spanner.admin.database.v1.IListBackupOperationsRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.longrunning.IOperation> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackupOperations'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackupOperations iterate %j', request);
    return this.descriptors.page.listBackupOperations.asyncIterate(
      this.innerApiCalls['listBackupOperations'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.longrunning.IOperation>;
  }
  /**
   * Lists Cloud Spanner database roles.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The database whose roles should be listed.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {number} request.pageSize
   *   Number of database roles to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse|ListDatabaseRolesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.spanner.admin.database.v1.DatabaseRole|DatabaseRole}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listDatabaseRolesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseRoles(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabaseRole[],
      protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse,
    ]
  >;
  listDatabaseRoles(
    request: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabaseRole
    >,
  ): void;
  listDatabaseRoles(
    request: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabaseRole
    >,
  ): void;
  listDatabaseRoles(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
          | protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IDatabaseRole
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
      | protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IDatabaseRole
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IDatabaseRole[],
      protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest | null,
      protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
          | protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IDatabaseRole
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listDatabaseRoles values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listDatabaseRoles request %j', request);
    return this.innerApiCalls
      .listDatabaseRoles(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.spanner.admin.database.v1.IDatabaseRole[],
          protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest | null,
          protos.google.spanner.admin.database.v1.IListDatabaseRolesResponse,
        ]) => {
          this._log.info('listDatabaseRoles values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listDatabaseRoles`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The database whose roles should be listed.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {number} request.pageSize
   *   Number of database roles to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse|ListDatabaseRolesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.spanner.admin.database.v1.DatabaseRole|DatabaseRole} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listDatabaseRolesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseRolesStream(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabaseRoles'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabaseRoles stream %j', request);
    return this.descriptors.page.listDatabaseRoles.createStream(
      this.innerApiCalls.listDatabaseRoles as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listDatabaseRoles`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. The database whose roles should be listed.
   *   Values are of the form
   *   `projects/<project>/instances/<instance>/databases/<database>`.
   * @param {number} request.pageSize
   *   Number of database roles to be returned in the response. If 0 or less,
   *   defaults to the server's maximum allowed page size.
   * @param {string} request.pageToken
   *   If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListDatabaseRolesResponse|ListDatabaseRolesResponse}.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.spanner.admin.database.v1.DatabaseRole|DatabaseRole}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listDatabaseRolesAsync(
    request?: protos.google.spanner.admin.database.v1.IListDatabaseRolesRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.spanner.admin.database.v1.IDatabaseRole> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listDatabaseRoles'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listDatabaseRoles iterate %j', request);
    return this.descriptors.page.listDatabaseRoles.asyncIterate(
      this.innerApiCalls['listDatabaseRoles'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.spanner.admin.database.v1.IDatabaseRole>;
  }
  /**
   * Lists all the backup schedules for the database.
   *
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. Database is the parent resource whose backup schedules should be
   *   listed. Values are of the form
   *   projects/<project>/instances/<instance>/databases/<database>
   * @param {number} [request.pageSize]
   *   Optional. Number of backup schedules to be returned in the response. If 0
   *   or less, defaults to the server's maximum allowed page size.
   * @param {string} [request.pageToken]
   *   Optional. If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse|ListBackupSchedulesResponse}
   *   to the same `parent`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Promise} - The promise which resolves to an array.
   *   The first element of the array is Array of {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule}.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed and will merge results from all the pages into this array.
   *   Note that it can affect your quota.
   *   We recommend using `listBackupSchedulesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupSchedules(
    request?: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    options?: CallOptions,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule[],
      protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse,
    ]
  >;
  listBackupSchedules(
    request: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    options: CallOptions,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
      | protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackupSchedule
    >,
  ): void;
  listBackupSchedules(
    request: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    callback: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
      | protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackupSchedule
    >,
  ): void;
  listBackupSchedules(
    request?: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    optionsOrCallback?:
      | CallOptions
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
          | protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IBackupSchedule
        >,
    callback?: PaginationCallback<
      protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
      | protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse
      | null
      | undefined,
      protos.google.spanner.admin.database.v1.IBackupSchedule
    >,
  ): Promise<
    [
      protos.google.spanner.admin.database.v1.IBackupSchedule[],
      protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest | null,
      protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse,
    ]
  > | void {
    request = request || {};
    let options: CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    this.initialize().catch(err => {
      throw err;
    });
    const wrappedCallback:
      | PaginationCallback<
          protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
          | protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse
          | null
          | undefined,
          protos.google.spanner.admin.database.v1.IBackupSchedule
        >
      | undefined = callback
      ? (error, values, nextPageRequest, rawResponse) => {
          this._log.info('listBackupSchedules values %j', values);
          callback!(error, values, nextPageRequest, rawResponse); // We verified callback above.
        }
      : undefined;
    this._log.info('listBackupSchedules request %j', request);
    return this.innerApiCalls
      .listBackupSchedules(request, options, wrappedCallback)
      ?.then(
        ([response, input, output]: [
          protos.google.spanner.admin.database.v1.IBackupSchedule[],
          protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest | null,
          protos.google.spanner.admin.database.v1.IListBackupSchedulesResponse,
        ]) => {
          this._log.info('listBackupSchedules values %j', response);
          return [response, input, output];
        },
      );
  }

  /**
   * Equivalent to `listBackupSchedules`, but returns a NodeJS Stream object.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. Database is the parent resource whose backup schedules should be
   *   listed. Values are of the form
   *   projects/<project>/instances/<instance>/databases/<database>
   * @param {number} [request.pageSize]
   *   Optional. Number of backup schedules to be returned in the response. If 0
   *   or less, defaults to the server's maximum allowed page size.
   * @param {string} [request.pageToken]
   *   Optional. If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse|ListBackupSchedulesResponse}
   *   to the same `parent`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Stream}
   *   An object stream which emits an object representing {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule} on 'data' event.
   *   The client library will perform auto-pagination by default: it will call the API as many
   *   times as needed. Note that it can affect your quota.
   *   We recommend using `listBackupSchedulesAsync()`
   *   method described below for async iteration which you can stop as needed.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupSchedulesStream(
    request?: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    options?: CallOptions,
  ): Transform {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackupSchedules'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackupSchedules stream %j', request);
    return this.descriptors.page.listBackupSchedules.createStream(
      this.innerApiCalls.listBackupSchedules as GaxCall,
      request,
      callSettings,
    );
  }

  /**
   * Equivalent to `listBackupSchedules`, but returns an iterable object.
   *
   * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand.
   * @param {Object} request
   *   The request object that will be sent.
   * @param {string} request.parent
   *   Required. Database is the parent resource whose backup schedules should be
   *   listed. Values are of the form
   *   projects/<project>/instances/<instance>/databases/<database>
   * @param {number} [request.pageSize]
   *   Optional. Number of backup schedules to be returned in the response. If 0
   *   or less, defaults to the server's maximum allowed page size.
   * @param {string} [request.pageToken]
   *   Optional. If non-empty, `page_token` should contain a
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse.next_page_token|next_page_token}
   *   from a previous
   *   {@link protos.google.spanner.admin.database.v1.ListBackupSchedulesResponse|ListBackupSchedulesResponse}
   *   to the same `parent`.
   * @param {object} [options]
   *   Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
   * @returns {Object}
   *   An iterable Object that allows {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | async iteration }.
   *   When you iterate the returned iterable, each element will be an object representing
   *   {@link protos.google.spanner.admin.database.v1.BackupSchedule|BackupSchedule}. The API will be called under the hood as needed, once per the page,
   *   so you can stop the iteration when you don't need more results.
   *   Please see the {@link https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination | documentation }
   *   for more details and examples.
   */
  listBackupSchedulesAsync(
    request?: protos.google.spanner.admin.database.v1.IListBackupSchedulesRequest,
    options?: CallOptions,
  ): AsyncIterable<protos.google.spanner.admin.database.v1.IBackupSchedule> {
    request = request || {};
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        parent: request.parent ?? '',
      });
    const defaultCallSettings = this._defaults['listBackupSchedules'];
    const callSettings = defaultCallSettings.merge(options);
    this.initialize().catch(err => {
      throw err;
    });
    this._log.info('listBackupSchedules iterate %j', request);
    return this.descriptors.page.listBackupSchedules.asyncIterate(
      this.innerApiCalls['listBackupSchedules'] as GaxCall,
      request as {},
      callSettings,
    ) as AsyncIterable<protos.google.spanner.admin.database.v1.IBackupSchedule>;
  }
  /**
   * Gets the latest state of a long-running operation.  Clients can use this
   * method to poll the operation result at intervals as recommended by the API
   * service.
   *
   * @param {Object} request - The request object that will be sent.
   * @param {string} request.name - The name of the operation resource.
   * @param {Object=} options
   *   Optional parameters. You can override the default settings for this call,
   *   e.g, timeout, retries, paginations, etc. See {@link
   *   https://googleapis.github.io/gax-nodejs/global.html#CallOptions | gax.CallOptions}
   *   for the details.
   * @param {function(?Error, ?Object)=} callback
   *   The function which will be called with the result of the API call.
   *
   *   The second parameter to the callback is an object representing
   *   {@link google.longrunning.Operation | google.longrunning.Operation}.
   * @return {Promise} - The promise which resolves to an array.
   *   The first element of the array is an object representing
   * {@link google.longrunning.Operation | google.longrunning.Operation}.
   * The promise has a method named "cancel" which cancels the ongoing API call.
   *
   * @example
   * ```
   * const client = longrunning.operationsClient();
   * const name = '';
   * const [response] = await client.getOperation({name});
   * // doThingsWith(response)
   * ```
   */
  getOperation(
    request: protos.google.longrunning.GetOperationRequest,
    optionsOrCallback?:
      | gax.CallOptions
      | Callback<
          protos.google.longrunning.Operation,
          protos.google.longrunning.GetOperationRequest,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.longrunning.Operation,
      protos.google.longrunning.GetOperationRequest,
      {} | null | undefined
    >,
  ): Promise<[protos.google.longrunning.Operation]> {
    let options: gax.CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as gax.CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    return this.operationsClient.getOperation(request, options, callback);
  }
  /**
   * Lists operations that match the specified filter in the request. If the
   * server doesn't support this method, it returns `UNIMPLEMENTED`. Returns an iterable object.
   *
   * For-await-of syntax is used with the iterable to recursively get response element on-demand.
   *
   * @param {Object} request - The request object that will be sent.
   * @param {string} request.name - The name of the operation collection.
   * @param {string} request.filter - The standard list filter.
   * @param {number=} request.pageSize -
   *   The maximum number of resources contained in the underlying API
   *   response. If page streaming is performed per-resource, this
   *   parameter does not affect the return value. If page streaming is
   *   performed per-page, this determines the maximum number of
   *   resources in a page.
   * @param {Object=} options
   *   Optional parameters. You can override the default settings for this call,
   *   e.g, timeout, retries, paginations, etc. See {@link
   *   https://googleapis.github.io/gax-nodejs/global.html#CallOptions | gax.CallOptions} for the
   *   details.
   * @returns {Object}
   *   An iterable Object that conforms to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | iteration protocols}.
   *
   * @example
   * ```
   * const client = longrunning.operationsClient();
   * for await (const response of client.listOperationsAsync(request));
   * // doThingsWith(response)
   * ```
   */
  listOperationsAsync(
    request: protos.google.longrunning.ListOperationsRequest,
    options?: gax.CallOptions,
  ): AsyncIterable<protos.google.longrunning.IOperation> {
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    return this.operationsClient.listOperationsAsync(request, options);
  }
  /**
   * Starts asynchronous cancellation on a long-running operation.  The server
   * makes a best effort to cancel the operation, but success is not
   * guaranteed.  If the server doesn't support this method, it returns
   * `google.rpc.Code.UNIMPLEMENTED`.  Clients can use
   * {@link Operations.GetOperation} or
   * other methods to check whether the cancellation succeeded or whether the
   * operation completed despite cancellation. On successful cancellation,
   * the operation is not deleted; instead, it becomes an operation with
   * an {@link Operation.error} value with a {@link google.rpc.Status.code} of
   * 1, corresponding to `Code.CANCELLED`.
   *
   * @param {Object} request - The request object that will be sent.
   * @param {string} request.name - The name of the operation resource to be cancelled.
   * @param {Object=} options
   *   Optional parameters. You can override the default settings for this call,
   * e.g, timeout, retries, paginations, etc. See {@link
   * https://googleapis.github.io/gax-nodejs/global.html#CallOptions | gax.CallOptions} for the
   * details.
   * @param {function(?Error)=} callback
   *   The function which will be called with the result of the API call.
   * @return {Promise} - The promise which resolves when API call finishes.
   *   The promise has a method named "cancel" which cancels the ongoing API
   * call.
   *
   * @example
   * ```
   * const client = longrunning.operationsClient();
   * await client.cancelOperation({name: ''});
   * ```
   */
  cancelOperation(
    request: protos.google.longrunning.CancelOperationRequest,
    optionsOrCallback?:
      | gax.CallOptions
      | Callback<
          protos.google.longrunning.CancelOperationRequest,
          protos.google.protobuf.Empty,
          {} | undefined | null
        >,
    callback?: Callback<
      protos.google.longrunning.CancelOperationRequest,
      protos.google.protobuf.Empty,
      {} | undefined | null
    >,
  ): Promise<protos.google.protobuf.Empty> {
    let options: gax.CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as gax.CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    return this.operationsClient.cancelOperation(request, options, callback);
  }

  /**
   * Deletes a long-running operation. This method indicates that the client is
   * no longer interested in the operation result. It does not cancel the
   * operation. If the server doesn't support this method, it returns
   * `google.rpc.Code.UNIMPLEMENTED`.
   *
   * @param {Object} request - The request object that will be sent.
   * @param {string} request.name - The name of the operation resource to be deleted.
   * @param {Object=} options
   *   Optional parameters. You can override the default settings for this call,
   * e.g, timeout, retries, paginations, etc. See {@link
   * https://googleapis.github.io/gax-nodejs/global.html#CallOptions | gax.CallOptions}
   * for the details.
   * @param {function(?Error)=} callback
   *   The function which will be called with the result of the API call.
   * @return {Promise} - The promise which resolves when API call finishes.
   *   The promise has a method named "cancel" which cancels the ongoing API
   * call.
   *
   * @example
   * ```
   * const client = longrunning.operationsClient();
   * await client.deleteOperation({name: ''});
   * ```
   */
  deleteOperation(
    request: protos.google.longrunning.DeleteOperationRequest,
    optionsOrCallback?:
      | gax.CallOptions
      | Callback<
          protos.google.protobuf.Empty,
          protos.google.longrunning.DeleteOperationRequest,
          {} | null | undefined
        >,
    callback?: Callback<
      protos.google.protobuf.Empty,
      protos.google.longrunning.DeleteOperationRequest,
      {} | null | undefined
    >,
  ): Promise<protos.google.protobuf.Empty> {
    let options: gax.CallOptions;
    if (typeof optionsOrCallback === 'function' && callback === undefined) {
      callback = optionsOrCallback;
      options = {};
    } else {
      options = optionsOrCallback as gax.CallOptions;
    }
    options = options || {};
    options.otherArgs = options.otherArgs || {};
    options.otherArgs.headers = options.otherArgs.headers || {};
    options.otherArgs.headers['x-goog-request-params'] =
      this._gaxModule.routingHeader.fromParams({
        name: request.name ?? '',
      });
    return this.operationsClient.deleteOperation(request, options, callback);
  }

  // --------------------
  // -- Path templates --
  // --------------------

  /**
   * Return a fully-qualified backup resource name string.
   *
   * @param {string} project
   * @param {string} instance
   * @param {string} backup
   * @returns {string} Resource name string.
   */
  backupPath(project: string, instance: string, backup: string) {
    return this.pathTemplates.backupPathTemplate.render({
      project: project,
      instance: instance,
      backup: backup,
    });
  }

  /**
   * Parse the project from Backup resource.
   *
   * @param {string} backupName
   *   A fully-qualified path representing Backup resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromBackupName(backupName: string) {
    return this.pathTemplates.backupPathTemplate.match(backupName).project;
  }

  /**
   * Parse the instance from Backup resource.
   *
   * @param {string} backupName
   *   A fully-qualified path representing Backup resource.
   * @returns {string} A string representing the instance.
   */
  matchInstanceFromBackupName(backupName: string) {
    return this.pathTemplates.backupPathTemplate.match(backupName).instance;
  }

  /**
   * Parse the backup from Backup resource.
   *
   * @param {string} backupName
   *   A fully-qualified path representing Backup resource.
   * @returns {string} A string representing the backup.
   */
  matchBackupFromBackupName(backupName: string) {
    return this.pathTemplates.backupPathTemplate.match(backupName).backup;
  }

  /**
   * Return a fully-qualified backupSchedule resource name string.
   *
   * @param {string} project
   * @param {string} instance
   * @param {string} database
   * @param {string} schedule
   * @returns {string} Resource name string.
   */
  backupSchedulePath(
    project: string,
    instance: string,
    database: string,
    schedule: string,
  ) {
    return this.pathTemplates.backupSchedulePathTemplate.render({
      project: project,
      instance: instance,
      database: database,
      schedule: schedule,
    });
  }

  /**
   * Parse the project from BackupSchedule resource.
   *
   * @param {string} backupScheduleName
   *   A fully-qualified path representing BackupSchedule resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromBackupScheduleName(backupScheduleName: string) {
    return this.pathTemplates.backupSchedulePathTemplate.match(
      backupScheduleName,
    ).project;
  }

  /**
   * Parse the instance from BackupSchedule resource.
   *
   * @param {string} backupScheduleName
   *   A fully-qualified path representing BackupSchedule resource.
   * @returns {string} A string representing the instance.
   */
  matchInstanceFromBackupScheduleName(backupScheduleName: string) {
    return this.pathTemplates.backupSchedulePathTemplate.match(
      backupScheduleName,
    ).instance;
  }

  /**
   * Parse the database from BackupSchedule resource.
   *
   * @param {string} backupScheduleName
   *   A fully-qualified path representing BackupSchedule resource.
   * @returns {string} A string representing the database.
   */
  matchDatabaseFromBackupScheduleName(backupScheduleName: string) {
    return this.pathTemplates.backupSchedulePathTemplate.match(
      backupScheduleName,
    ).database;
  }

  /**
   * Parse the schedule from BackupSchedule resource.
   *
   * @param {string} backupScheduleName
   *   A fully-qualified path representing BackupSchedule resource.
   * @returns {string} A string representing the schedule.
   */
  matchScheduleFromBackupScheduleName(backupScheduleName: string) {
    return this.pathTemplates.backupSchedulePathTemplate.match(
      backupScheduleName,
    ).schedule;
  }

  /**
   * Return a fully-qualified cryptoKey resource name string.
   *
   * @param {string} project
   * @param {string} location
   * @param {string} key_ring
   * @param {string} crypto_key
   * @returns {string} Resource name string.
   */
  cryptoKeyPath(
    project: string,
    location: string,
    keyRing: string,
    cryptoKey: string,
  ) {
    return this.pathTemplates.cryptoKeyPathTemplate.render({
      project: project,
      location: location,
      key_ring: keyRing,
      crypto_key: cryptoKey,
    });
  }

  /**
   * Parse the project from CryptoKey resource.
   *
   * @param {string} cryptoKeyName
   *   A fully-qualified path representing CryptoKey resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromCryptoKeyName(cryptoKeyName: string) {
    return this.pathTemplates.cryptoKeyPathTemplate.match(cryptoKeyName)
      .project;
  }

  /**
   * Parse the location from CryptoKey resource.
   *
   * @param {string} cryptoKeyName
   *   A fully-qualified path representing CryptoKey resource.
   * @returns {string} A string representing the location.
   */
  matchLocationFromCryptoKeyName(cryptoKeyName: string) {
    return this.pathTemplates.cryptoKeyPathTemplate.match(cryptoKeyName)
      .location;
  }

  /**
   * Parse the key_ring from CryptoKey resource.
   *
   * @param {string} cryptoKeyName
   *   A fully-qualified path representing CryptoKey resource.
   * @returns {string} A string representing the key_ring.
   */
  matchKeyRingFromCryptoKeyName(cryptoKeyName: string) {
    return this.pathTemplates.cryptoKeyPathTemplate.match(cryptoKeyName)
      .key_ring;
  }

  /**
   * Parse the crypto_key from CryptoKey resource.
   *
   * @param {string} cryptoKeyName
   *   A fully-qualified path representing CryptoKey resource.
   * @returns {string} A string representing the crypto_key.
   */
  matchCryptoKeyFromCryptoKeyName(cryptoKeyName: string) {
    return this.pathTemplates.cryptoKeyPathTemplate.match(cryptoKeyName)
      .crypto_key;
  }

  /**
   * Return a fully-qualified database resource name string.
   *
   * @param {string} project
   * @param {string} instance
   * @param {string} database
   * @returns {string} Resource name string.
   */
  databasePath(project: string, instance: string, database: string) {
    return this.pathTemplates.databasePathTemplate.render({
      project: project,
      instance: instance,
      database: database,
    });
  }

  /**
   * Parse the project from Database resource.
   *
   * @param {string} databaseName
   *   A fully-qualified path representing Database resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromDatabaseName(databaseName: string) {
    return this.pathTemplates.databasePathTemplate.match(databaseName).project;
  }

  /**
   * Parse the instance from Database resource.
   *
   * @param {string} databaseName
   *   A fully-qualified path representing Database resource.
   * @returns {string} A string representing the instance.
   */
  matchInstanceFromDatabaseName(databaseName: string) {
    return this.pathTemplates.databasePathTemplate.match(databaseName).instance;
  }

  /**
   * Parse the database from Database resource.
   *
   * @param {string} databaseName
   *   A fully-qualified path representing Database resource.
   * @returns {string} A string representing the database.
   */
  matchDatabaseFromDatabaseName(databaseName: string) {
    return this.pathTemplates.databasePathTemplate.match(databaseName).database;
  }

  /**
   * Return a fully-qualified databaseRole resource name string.
   *
   * @param {string} project
   * @param {string} instance
   * @param {string} database
   * @param {string} role
   * @returns {string} Resource name string.
   */
  databaseRolePath(
    project: string,
    instance: string,
    database: string,
    role: string,
  ) {
    return this.pathTemplates.databaseRolePathTemplate.render({
      project: project,
      instance: instance,
      database: database,
      role: role,
    });
  }

  /**
   * Parse the project from DatabaseRole resource.
   *
   * @param {string} databaseRoleName
   *   A fully-qualified path representing DatabaseRole resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromDatabaseRoleName(databaseRoleName: string) {
    return this.pathTemplates.databaseRolePathTemplate.match(databaseRoleName)
      .project;
  }

  /**
   * Parse the instance from DatabaseRole resource.
   *
   * @param {string} databaseRoleName
   *   A fully-qualified path representing DatabaseRole resource.
   * @returns {string} A string representing the instance.
   */
  matchInstanceFromDatabaseRoleName(databaseRoleName: string) {
    return this.pathTemplates.databaseRolePathTemplate.match(databaseRoleName)
      .instance;
  }

  /**
   * Parse the database from DatabaseRole resource.
   *
   * @param {string} databaseRoleName
   *   A fully-qualified path representing DatabaseRole resource.
   * @returns {string} A string representing the database.
   */
  matchDatabaseFromDatabaseRoleName(databaseRoleName: string) {
    return this.pathTemplates.databaseRolePathTemplate.match(databaseRoleName)
      .database;
  }

  /**
   * Parse the role from DatabaseRole resource.
   *
   * @param {string} databaseRoleName
   *   A fully-qualified path representing DatabaseRole resource.
   * @returns {string} A string representing the role.
   */
  matchRoleFromDatabaseRoleName(databaseRoleName: string) {
    return this.pathTemplates.databaseRolePathTemplate.match(databaseRoleName)
      .role;
  }

  /**
   * Return a fully-qualified instance resource name string.
   *
   * @param {string} project
   * @param {string} instance
   * @returns {string} Resource name string.
   */
  instancePath(project: string, instance: string) {
    return this.pathTemplates.instancePathTemplate.render({
      project: project,
      instance: instance,
    });
  }

  /**
   * Parse the project from Instance resource.
   *
   * @param {string} instanceName
   *   A fully-qualified path representing Instance resource.
   * @returns {string} A string representing the project.
   */
  matchProjectFromInstanceName(instanceName: string) {
    return this.pathTemplates.instancePathTemplate.match(instanceName).project;
  }

  /**
   * Parse the instance from Instance resource.
   *
   * @param {string} instanceName
   *   A fully-qualified path representing Instance resource.
   * @returns {string} A string representing the instance.
   */
  matchInstanceFromInstanceName(instanceName: string) {
    return this.pathTemplates.instancePathTemplate.match(instanceName).instance;
  }

  /**
   * Terminate the gRPC channel and close the client.
   *
   * The client will no longer be usable and all future behavior is undefined.
   * @returns {Promise} A promise that resolves when the client is closed.
   */
  close(): Promise<void> {
    if (this.databaseAdminStub && !this._terminated) {
      return this.databaseAdminStub.then(stub => {
        this._log.info('ending gRPC channel');
        this._terminated = true;
        stub.close();
        void this.operationsClient.close();
      });
    }
    return Promise.resolve();
  }
}
