/*!
 * Copyright 2019 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { grpc } from 'google-gax';
import { Session } from './session';
import { Transaction } from './transaction';
import { NormalCallback } from './common';
import { protos } from '@google-cloud/spanner-api';
import google = protos.google;
import IRequestOptions = google.spanner.v1.IRequestOptions;
import IsolationLevel = google.spanner.v1.TransactionOptions.IsolationLevel;
import ReadLockMode = google.spanner.v1.TransactionOptions.ReadWrite.ReadLockMode;
/**
 * @typedef {object} RunTransactionOptions
 * @property {number} [timeout] The maximum amount of time (in ms) that a
 *     {@link Transaction} should be ran for.
 */
export interface RunTransactionOptions {
    timeout?: number;
    requestOptions?: Pick<IRequestOptions, 'transactionTag'>;
    /**
     * @deprecated Use readLockMode instead.
     */
    optimisticLock?: boolean;
    excludeTxnFromChangeStreams?: boolean;
    isolationLevel?: IsolationLevel;
    readLockMode?: ReadLockMode;
}
/**
 * A function to execute in the context of a transaction.
 * @callback RunTransactionCallback
 * @param {?Error} err An error returned while making this request.
 * @param {Transaction} transaction The transaction object. The transaction has
 *     already been created, and is ready to be queried and committed against.
 */
export type RunTransactionCallback = NormalCallback<Transaction>;
/**
 * A function to execute in the context of a transaction.
 * @callback AsyncRunTransactionCallback
 * @param {Transaction} transaction The transaction object. The transaction has
 *     already been created, and is ready to be queried and committed against.
 */
export interface AsyncRunTransactionCallback<T> {
    (transaction: Transaction): Promise<T>;
}
/**
 * Error class used to signal a Transaction timeout.
 *
 * @private
 * @class
 *
 * @param {Error} [err] The last known retryable Error.
 */
export declare class DeadlineError extends Error implements grpc.ServiceError {
    code: grpc.status;
    details: string;
    metadata: grpc.Metadata;
    errors: grpc.ServiceError[];
    constructor(error?: grpc.ServiceError);
}
/**
 * Base class for running/retrying Transactions.
 *
 * @private
 * @class
 * @abstract
 *
 * @param {Database} database The Database to pull Sessions/Transactions from.
 * @param {RunTransactionOptions} [options] The runner options.
 */
export declare abstract class Runner<T> {
    abstract runFn: Function;
    attempts: number;
    session: Session;
    transaction?: Transaction;
    options: RunTransactionOptions;
    multiplexedSessionPreviousTransactionId?: Uint8Array | string;
    constructor(session: Session, transaction: Transaction, options?: RunTransactionOptions);
    /**
     * Runs the user function against the provided transaction. Resolving the
     * returned Promise upon completion/error.
     *
     * @private
     *
     * @param {Transaction} transaction The transaction to run against.
     * @returns {Promise}
     */
    protected abstract _run(transaction: Transaction): Promise<T>;
    /**
     * Attempts to retrieve the retry delay from the supplied error. If absent it
     * will create one based on the number of attempts made thus far.
     *
     * @private
     *
     * @param {Error} err The service error.
     * @returns {number} Delay in milliseconds.
     */
    getNextDelay(err: grpc.ServiceError): number;
    /** Returns whether the given error should cause a transaction retry. */
    shouldRetry(err: grpc.ServiceError): boolean;
    /**
     * Retrieves a transaction to run against.
     *
     * @private
     *
     * @returns Promise<Transaction>
     */
    getTransaction(): Promise<Transaction>;
    /**
     * This function is responsible for getting transactions, running them and
     * handling any errors, retrying if necessary.
     *
     * @private
     *
     * @returns {Promise}
     */
    run(): Promise<T>;
}
/**
 * This class handles transactions expecting to be ran in callback mode.
 *
 * @private
 * @class
 *
 * @param {Database} database The database to pull sessions/transactions from.
 * @param {RunTransactionCallback} runFn The user supplied run function.
 * @param {RunTransactionOptions} [options] Runner options.
 */
export declare class TransactionRunner extends Runner<void> {
    runFn: RunTransactionCallback;
    constructor(session: Session, transaction: Transaction, runFn: RunTransactionCallback, options?: RunTransactionOptions);
    /**
     * Because the user has decided to use callback mode, we want to try and
     * intercept any ABORTED or UNKNOWN errors and stop the current function
     * execution.
     *
     * @private
     *
     * @param {Transaction} transaction The transaction to intercept errors for.
     * @param {Function} reject Function to call when a retryable error is found.
     */
    private _interceptErrors;
    /**
     * Creates a Promise that should resolve when the provided transaction has
     * been committed or rolled back. Rejects if a retryable error occurs.
     *
     * @private
     *
     * @param {Transaction}
     * @returns {Promise}
     */
    protected _run(transaction: Transaction): Promise<void>;
}
/**
 * This class handles transactions expecting to be ran in promise mode.
 *
 * @private
 * @class
 *
 * @param {Database} database The database to pull sessions/transactions from.
 * @param {AsyncRunTransactionCallback} runFn The user supplied run function.
 * @param {RunTransactionOptions} [options] Runner options.
 */
export declare class AsyncTransactionRunner<T> extends Runner<T> {
    runFn: AsyncRunTransactionCallback<T>;
    constructor(session: Session, transaction: Transaction, runFn: AsyncRunTransactionCallback<T>, options?: RunTransactionOptions);
    /**
     * Since this is promise mode all we need to do is return the user function.
     *
     * @private
     *
     * @param {Transaction} transaction The transaction to be ran against.
     * @returns {Promise}
     */
    protected _run(transaction: Transaction): Promise<T>;
}
/**
 * Checks whether the given error is a retryable internal error.
 * @param error the error to check
 * @return true if the error is a retryable internal error, and otherwise false.
 */
export declare function isRetryableInternalError(err: grpc.ServiceError): boolean;
