// This is a generated file (see the discoveryapis_generator project).

library googleapis.datastore.v1;

import 'dart:core' as core;
import 'dart:async' as async;
import 'dart:convert' as convert;

import 'package:_discoveryapis_commons/_discoveryapis_commons.dart' as commons;
import 'package:http/http.dart' as http;

export 'package:_discoveryapis_commons/_discoveryapis_commons.dart'
    show ApiRequestError, DetailedApiRequestError;

const core.String USER_AGENT = 'dart-api-client datastore/v1';

/// Accesses the schemaless NoSQL database to provide fully managed, robust,
/// scalable storage for your application.
class DatastoreApi {
  /// View and manage your data across Google Cloud Platform services
  static const CloudPlatformScope =
      "https://www.googleapis.com/auth/cloud-platform";

  /// View and manage your Google Cloud Datastore data
  static const DatastoreScope = "https://www.googleapis.com/auth/datastore";

  final commons.ApiRequester _requester;

  ProjectsResourceApi get projects => new ProjectsResourceApi(_requester);

  DatastoreApi(http.Client client,
      {core.String rootUrl: "https://datastore.googleapis.com/",
      core.String servicePath: ""})
      : _requester =
            new commons.ApiRequester(client, rootUrl, servicePath, USER_AGENT);
}

class ProjectsResourceApi {
  final commons.ApiRequester _requester;

  ProjectsOperationsResourceApi get operations =>
      new ProjectsOperationsResourceApi(_requester);

  ProjectsResourceApi(commons.ApiRequester client) : _requester = client;

  /// Allocates IDs for the given keys, which is useful for referencing an
  /// entity
  /// before it is inserted.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [AllocateIdsResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<AllocateIdsResponse> allocateIds(
      AllocateIdsRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':allocateIds';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new AllocateIdsResponse.fromJson(data));
  }

  /// Begins a new transaction.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [BeginTransactionResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<BeginTransactionResponse> beginTransaction(
      BeginTransactionRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':beginTransaction';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response
        .then((data) => new BeginTransactionResponse.fromJson(data));
  }

  /// Commits a transaction, optionally creating, deleting or modifying some
  /// entities.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [CommitResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<CommitResponse> commit(
      CommitRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':commit';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new CommitResponse.fromJson(data));
  }

  /// Looks up entities by key.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [LookupResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<LookupResponse> lookup(
      LookupRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':lookup';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new LookupResponse.fromJson(data));
  }

  /// Prevents the supplied keys' IDs from being auto-allocated by Cloud
  /// Datastore.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [ReserveIdsResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<ReserveIdsResponse> reserveIds(
      ReserveIdsRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':reserveIds';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new ReserveIdsResponse.fromJson(data));
  }

  /// Rolls back a transaction.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [RollbackResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<RollbackResponse> rollback(
      RollbackRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':rollback';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new RollbackResponse.fromJson(data));
  }

  /// Queries for entities.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [projectId] - The ID of the project against which to make the request.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [RunQueryResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<RunQueryResponse> runQuery(
      RunQueryRequest request, core.String projectId,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (projectId == null) {
      throw new core.ArgumentError("Parameter projectId is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/projects/' +
        commons.Escaper.ecapeVariable('$projectId') +
        ':runQuery';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new RunQueryResponse.fromJson(data));
  }
}

class ProjectsOperationsResourceApi {
  final commons.ApiRequester _requester;

  ProjectsOperationsResourceApi(commons.ApiRequester client)
      : _requester = client;

  /// 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
  /// 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 Operation.error value with a google.rpc.Status.code of 1,
  /// corresponding to `Code.CANCELLED`.
  ///
  /// Request parameters:
  ///
  /// [name] - The name of the operation resource to be cancelled.
  /// Value must have pattern "^projects/[^/]+/operations/[^/]+$".
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Empty].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Empty> cancel(core.String name, {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (name == null) {
      throw new core.ArgumentError("Parameter name is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/' + commons.Escaper.ecapeVariableReserved('$name') + ':cancel';

    var _response = _requester.request(_url, "POST",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new Empty.fromJson(data));
  }

  /// 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`.
  ///
  /// Request parameters:
  ///
  /// [name] - The name of the operation resource to be deleted.
  /// Value must have pattern "^projects/[^/]+/operations/[^/]+$".
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [Empty].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<Empty> delete(core.String name, {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (name == null) {
      throw new core.ArgumentError("Parameter name is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/' + commons.Escaper.ecapeVariableReserved('$name');

    var _response = _requester.request(_url, "DELETE",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then((data) => new Empty.fromJson(data));
  }

  /// 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.
  ///
  /// Request parameters:
  ///
  /// [name] - The name of the operation resource.
  /// Value must have pattern "^projects/[^/]+/operations/[^/]+$".
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [GoogleLongrunningOperation].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<GoogleLongrunningOperation> get(core.String name,
      {core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (name == null) {
      throw new core.ArgumentError("Parameter name is required.");
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url = 'v1/' + commons.Escaper.ecapeVariableReserved('$name');

    var _response = _requester.request(_url, "GET",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response
        .then((data) => new GoogleLongrunningOperation.fromJson(data));
  }

  /// Lists operations that match the specified filter in the request. If the
  /// server doesn't support this method, it returns `UNIMPLEMENTED`.
  ///
  /// NOTE: the `name` binding allows API services to override the binding
  /// to use different resource name schemes, such as `users / * /operations`.
  /// To
  /// override the binding, API services can add a binding such as
  /// `"/v1/{name=users / * }/operations"` to their service configuration.
  /// For backwards compatibility, the default name includes the operations
  /// collection id, however overriding users must ensure the name binding
  /// is the parent resource, without the operations collection id.
  ///
  /// Request parameters:
  ///
  /// [name] - The name of the operation's parent resource.
  /// Value must have pattern "^projects/[^/]+$".
  ///
  /// [pageToken] - The standard list page token.
  ///
  /// [pageSize] - The standard list page size.
  ///
  /// [filter] - The standard list filter.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [GoogleLongrunningListOperationsResponse].
  ///
  /// Completes with a [commons.ApiRequestError] if the API endpoint returned an
  /// error.
  ///
  /// If the used [http.Client] completes with an error when making a REST call,
  /// this method will complete with the same error.
  async.Future<GoogleLongrunningListOperationsResponse> list(core.String name,
      {core.String pageToken,
      core.int pageSize,
      core.String filter,
      core.String $fields}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    var _body = null;

    if (name == null) {
      throw new core.ArgumentError("Parameter name is required.");
    }
    if (pageToken != null) {
      _queryParams["pageToken"] = [pageToken];
    }
    if (pageSize != null) {
      _queryParams["pageSize"] = ["${pageSize}"];
    }
    if (filter != null) {
      _queryParams["filter"] = [filter];
    }
    if ($fields != null) {
      _queryParams["fields"] = [$fields];
    }

    _url =
        'v1/' + commons.Escaper.ecapeVariableReserved('$name') + '/operations';

    var _response = _requester.request(_url, "GET",
        body: _body,
        queryParams: _queryParams,
        uploadOptions: _uploadOptions,
        uploadMedia: _uploadMedia,
        downloadOptions: _downloadOptions);
    return _response.then(
        (data) => new GoogleLongrunningListOperationsResponse.fromJson(data));
  }
}

/// The request for Datastore.AllocateIds.
class AllocateIdsRequest {
  /// A list of keys with incomplete key paths for which to allocate IDs.
  /// No key may be reserved/read-only.
  core.List<Key> keys;

  AllocateIdsRequest();

  AllocateIdsRequest.fromJson(core.Map _json) {
    if (_json.containsKey("keys")) {
      keys = _json["keys"].map((value) => new Key.fromJson(value)).toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (keys != null) {
      _json["keys"] = keys.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// The response for Datastore.AllocateIds.
class AllocateIdsResponse {
  /// The keys specified in the request (in the same order), each with
  /// its key path completed with a newly allocated ID.
  core.List<Key> keys;

  AllocateIdsResponse();

  AllocateIdsResponse.fromJson(core.Map _json) {
    if (_json.containsKey("keys")) {
      keys = _json["keys"].map((value) => new Key.fromJson(value)).toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (keys != null) {
      _json["keys"] = keys.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// An array value.
class ArrayValue {
  /// Values in the array.
  /// The order of this array may not be preserved if it contains a mix of
  /// indexed and unindexed values.
  core.List<Value> values;

  ArrayValue();

  ArrayValue.fromJson(core.Map _json) {
    if (_json.containsKey("values")) {
      values =
          _json["values"].map((value) => new Value.fromJson(value)).toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (values != null) {
      _json["values"] = values.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// The request for Datastore.BeginTransaction.
class BeginTransactionRequest {
  /// Options for a new transaction.
  TransactionOptions transactionOptions;

  BeginTransactionRequest();

  BeginTransactionRequest.fromJson(core.Map _json) {
    if (_json.containsKey("transactionOptions")) {
      transactionOptions =
          new TransactionOptions.fromJson(_json["transactionOptions"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (transactionOptions != null) {
      _json["transactionOptions"] = (transactionOptions).toJson();
    }
    return _json;
  }
}

/// The response for Datastore.BeginTransaction.
class BeginTransactionResponse {
  /// The transaction identifier (always present).
  core.String transaction;
  core.List<core.int> get transactionAsBytes {
    return convert.BASE64.decode(transaction);
  }

  void set transactionAsBytes(core.List<core.int> _bytes) {
    transaction =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  BeginTransactionResponse();

  BeginTransactionResponse.fromJson(core.Map _json) {
    if (_json.containsKey("transaction")) {
      transaction = _json["transaction"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (transaction != null) {
      _json["transaction"] = transaction;
    }
    return _json;
  }
}

/// The request for Datastore.Commit.
class CommitRequest {
  /// The type of commit to perform. Defaults to `TRANSACTIONAL`.
  /// Possible string values are:
  /// - "MODE_UNSPECIFIED" : Unspecified. This value must not be used.
  /// - "TRANSACTIONAL" : Transactional: The mutations are either all applied,
  /// or none are applied.
  /// Learn about transactions
  /// [here](https://cloud.google.com/datastore/docs/concepts/transactions).
  /// - "NON_TRANSACTIONAL" : Non-transactional: The mutations may not apply as
  /// all or none.
  core.String mode;

  /// The mutations to perform.
  ///
  /// When mode is `TRANSACTIONAL`, mutations affecting a single entity are
  /// applied in order. The following sequences of mutations affecting a single
  /// entity are not permitted in a single `Commit` request:
  ///
  /// - `insert` followed by `insert`
  /// - `update` followed by `insert`
  /// - `upsert` followed by `insert`
  /// - `delete` followed by `update`
  ///
  /// When mode is `NON_TRANSACTIONAL`, no two mutations may affect a single
  /// entity.
  core.List<Mutation> mutations;

  /// The identifier of the transaction associated with the commit. A
  /// transaction identifier is returned by a call to
  /// Datastore.BeginTransaction.
  core.String transaction;
  core.List<core.int> get transactionAsBytes {
    return convert.BASE64.decode(transaction);
  }

  void set transactionAsBytes(core.List<core.int> _bytes) {
    transaction =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  CommitRequest();

  CommitRequest.fromJson(core.Map _json) {
    if (_json.containsKey("mode")) {
      mode = _json["mode"];
    }
    if (_json.containsKey("mutations")) {
      mutations = _json["mutations"]
          .map((value) => new Mutation.fromJson(value))
          .toList();
    }
    if (_json.containsKey("transaction")) {
      transaction = _json["transaction"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (mode != null) {
      _json["mode"] = mode;
    }
    if (mutations != null) {
      _json["mutations"] = mutations.map((value) => (value).toJson()).toList();
    }
    if (transaction != null) {
      _json["transaction"] = transaction;
    }
    return _json;
  }
}

/// The response for Datastore.Commit.
class CommitResponse {
  /// The number of index entries updated during the commit, or zero if none
  /// were
  /// updated.
  core.int indexUpdates;

  /// The result of performing the mutations.
  /// The i-th mutation result corresponds to the i-th mutation in the request.
  core.List<MutationResult> mutationResults;

  CommitResponse();

  CommitResponse.fromJson(core.Map _json) {
    if (_json.containsKey("indexUpdates")) {
      indexUpdates = _json["indexUpdates"];
    }
    if (_json.containsKey("mutationResults")) {
      mutationResults = _json["mutationResults"]
          .map((value) => new MutationResult.fromJson(value))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (indexUpdates != null) {
      _json["indexUpdates"] = indexUpdates;
    }
    if (mutationResults != null) {
      _json["mutationResults"] =
          mutationResults.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// A filter that merges multiple other filters using the given operator.
class CompositeFilter {
  /// The list of filters to combine.
  /// Must contain at least one filter.
  core.List<Filter> filters;

  /// The operator for combining multiple filters.
  /// Possible string values are:
  /// - "OPERATOR_UNSPECIFIED" : Unspecified. This value must not be used.
  /// - "AND" : The results are required to satisfy each of the combined
  /// filters.
  core.String op;

  CompositeFilter();

  CompositeFilter.fromJson(core.Map _json) {
    if (_json.containsKey("filters")) {
      filters =
          _json["filters"].map((value) => new Filter.fromJson(value)).toList();
    }
    if (_json.containsKey("op")) {
      op = _json["op"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (filters != null) {
      _json["filters"] = filters.map((value) => (value).toJson()).toList();
    }
    if (op != null) {
      _json["op"] = op;
    }
    return _json;
  }
}

/// A generic empty message that you can re-use to avoid defining duplicated
/// empty messages in your APIs. A typical example is to use it as the request
/// or the response type of an API method. For instance:
///
///     service Foo {
///       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
///     }
///
/// The JSON representation for `Empty` is empty JSON object `{}`.
class Empty {
  Empty();

  Empty.fromJson(core.Map _json) {}

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    return _json;
  }
}

/// A Datastore data object.
///
/// An entity is limited to 1 megabyte when stored. That _roughly_
/// corresponds to a limit of 1 megabyte for the serialized form of this
/// message.
class Entity {
  /// The entity's key.
  ///
  /// An entity must have a key, unless otherwise documented (for example,
  /// an entity in `Value.entity_value` may have no key).
  /// An entity's kind is its key path's last element's kind,
  /// or null if it has no key.
  Key key;

  /// The entity's properties.
  /// The map's keys are property names.
  /// A property name matching regex `__.*__` is reserved.
  /// A reserved property name is forbidden in certain documented contexts.
  /// The name must not contain more than 500 characters.
  /// The name cannot be `""`.
  core.Map<core.String, Value> properties;

  Entity();

  Entity.fromJson(core.Map _json) {
    if (_json.containsKey("key")) {
      key = new Key.fromJson(_json["key"]);
    }
    if (_json.containsKey("properties")) {
      properties = commons.mapMap<core.Map<core.String, core.Object>, Value>(
          _json["properties"],
          (core.Map<core.String, core.Object> item) =>
              new Value.fromJson(item));
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (key != null) {
      _json["key"] = (key).toJson();
    }
    if (properties != null) {
      _json["properties"] =
          commons.mapMap<Value, core.Map<core.String, core.Object>>(
              properties, (Value item) => (item).toJson());
    }
    return _json;
  }
}

/// The result of fetching an entity from Datastore.
class EntityResult {
  /// A cursor that points to the position after the result entity.
  /// Set only when the `EntityResult` is part of a `QueryResultBatch` message.
  core.String cursor;
  core.List<core.int> get cursorAsBytes {
    return convert.BASE64.decode(cursor);
  }

  void set cursorAsBytes(core.List<core.int> _bytes) {
    cursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// The resulting entity.
  Entity entity;

  /// The version of the entity, a strictly positive number that monotonically
  /// increases with changes to the entity.
  ///
  /// This field is set for `FULL` entity
  /// results.
  ///
  /// For missing entities in `LookupResponse`, this
  /// is the version of the snapshot that was used to look up the entity, and it
  /// is always set except for eventually consistent reads.
  core.String version;

  EntityResult();

  EntityResult.fromJson(core.Map _json) {
    if (_json.containsKey("cursor")) {
      cursor = _json["cursor"];
    }
    if (_json.containsKey("entity")) {
      entity = new Entity.fromJson(_json["entity"]);
    }
    if (_json.containsKey("version")) {
      version = _json["version"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (cursor != null) {
      _json["cursor"] = cursor;
    }
    if (entity != null) {
      _json["entity"] = (entity).toJson();
    }
    if (version != null) {
      _json["version"] = version;
    }
    return _json;
  }
}

/// A holder for any type of filter.
class Filter {
  /// A composite filter.
  CompositeFilter compositeFilter;

  /// A filter on a property.
  PropertyFilter propertyFilter;

  Filter();

  Filter.fromJson(core.Map _json) {
    if (_json.containsKey("compositeFilter")) {
      compositeFilter = new CompositeFilter.fromJson(_json["compositeFilter"]);
    }
    if (_json.containsKey("propertyFilter")) {
      propertyFilter = new PropertyFilter.fromJson(_json["propertyFilter"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (compositeFilter != null) {
      _json["compositeFilter"] = (compositeFilter).toJson();
    }
    if (propertyFilter != null) {
      _json["propertyFilter"] = (propertyFilter).toJson();
    }
    return _json;
  }
}

/// Metadata common to all Datastore Admin operations.
class GoogleDatastoreAdminV1beta1CommonMetadata {
  /// The time the operation ended, either successfully or otherwise.
  core.String endTime;

  /// The client-assigned labels which were provided when the operation was
  /// created. May also include additional labels.
  core.Map<core.String, core.String> labels;

  /// The type of the operation. Can be used as a filter in
  /// ListOperationsRequest.
  /// Possible string values are:
  /// - "OPERATION_TYPE_UNSPECIFIED" : Unspecified.
  /// - "EXPORT_ENTITIES" : ExportEntities.
  /// - "IMPORT_ENTITIES" : ImportEntities.
  core.String operationType;

  /// The time that work began on the operation.
  core.String startTime;

  /// The current state of the Operation.
  /// Possible string values are:
  /// - "STATE_UNSPECIFIED" : Unspecified.
  /// - "INITIALIZING" : Request is being prepared for processing.
  /// - "PROCESSING" : Request is actively being processed.
  /// - "CANCELLING" : Request is in the process of being cancelled after user
  /// called
  /// google.longrunning.Operations.CancelOperation on the operation.
  /// - "FINALIZING" : Request has been processed and is in its finalization
  /// stage.
  /// - "SUCCESSFUL" : Request has completed successfully.
  /// - "FAILED" : Request has finished being processed, but encountered an
  /// error.
  /// - "CANCELLED" : Request has finished being cancelled after user called
  /// google.longrunning.Operations.CancelOperation.
  core.String state;

  GoogleDatastoreAdminV1beta1CommonMetadata();

  GoogleDatastoreAdminV1beta1CommonMetadata.fromJson(core.Map _json) {
    if (_json.containsKey("endTime")) {
      endTime = _json["endTime"];
    }
    if (_json.containsKey("labels")) {
      labels = _json["labels"];
    }
    if (_json.containsKey("operationType")) {
      operationType = _json["operationType"];
    }
    if (_json.containsKey("startTime")) {
      startTime = _json["startTime"];
    }
    if (_json.containsKey("state")) {
      state = _json["state"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (endTime != null) {
      _json["endTime"] = endTime;
    }
    if (labels != null) {
      _json["labels"] = labels;
    }
    if (operationType != null) {
      _json["operationType"] = operationType;
    }
    if (startTime != null) {
      _json["startTime"] = startTime;
    }
    if (state != null) {
      _json["state"] = state;
    }
    return _json;
  }
}

/// Identifies a subset of entities in a project. This is specified as
/// combinations of kinds and namespaces (either or both of which may be all, as
/// described in the following examples).
/// Example usage:
///
/// Entire project:
///   kinds=[], namespace_ids=[]
///
/// Kinds Foo and Bar in all namespaces:
///   kinds=['Foo', 'Bar'], namespace_ids=[]
///
/// Kinds Foo and Bar only in the default namespace:
///   kinds=['Foo', 'Bar'], namespace_ids=['']
///
/// Kinds Foo and Bar in both the default and Baz namespaces:
///   kinds=['Foo', 'Bar'], namespace_ids=['', 'Baz']
///
/// The entire Baz namespace:
///   kinds=[], namespace_ids=['Baz']
class GoogleDatastoreAdminV1beta1EntityFilter {
  /// If empty, then this represents all kinds.
  core.List<core.String> kinds;

  /// An empty list represents all namespaces. This is the preferred
  /// usage for projects that don't use namespaces.
  ///
  /// An empty string element represents the default namespace. This should be
  /// used if the project has data in non-default namespaces, but doesn't want
  /// to
  /// include them.
  /// Each namespace in this list must be unique.
  core.List<core.String> namespaceIds;

  GoogleDatastoreAdminV1beta1EntityFilter();

  GoogleDatastoreAdminV1beta1EntityFilter.fromJson(core.Map _json) {
    if (_json.containsKey("kinds")) {
      kinds = _json["kinds"];
    }
    if (_json.containsKey("namespaceIds")) {
      namespaceIds = _json["namespaceIds"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (kinds != null) {
      _json["kinds"] = kinds;
    }
    if (namespaceIds != null) {
      _json["namespaceIds"] = namespaceIds;
    }
    return _json;
  }
}

/// Metadata for ExportEntities operations.
class GoogleDatastoreAdminV1beta1ExportEntitiesMetadata {
  /// Metadata common to all Datastore Admin operations.
  GoogleDatastoreAdminV1beta1CommonMetadata common;

  /// Description of which entities are being exported.
  GoogleDatastoreAdminV1beta1EntityFilter entityFilter;

  /// Location for the export metadata and data files. This will be the same
  /// value as the
  /// google.datastore.admin.v1beta1.ExportEntitiesRequest.output_url_prefix
  /// field. The final output location is provided in
  /// google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url.
  core.String outputUrlPrefix;

  /// An estimate of the number of bytes processed.
  GoogleDatastoreAdminV1beta1Progress progressBytes;

  /// An estimate of the number of entities processed.
  GoogleDatastoreAdminV1beta1Progress progressEntities;

  GoogleDatastoreAdminV1beta1ExportEntitiesMetadata();

  GoogleDatastoreAdminV1beta1ExportEntitiesMetadata.fromJson(core.Map _json) {
    if (_json.containsKey("common")) {
      common = new GoogleDatastoreAdminV1beta1CommonMetadata.fromJson(
          _json["common"]);
    }
    if (_json.containsKey("entityFilter")) {
      entityFilter = new GoogleDatastoreAdminV1beta1EntityFilter.fromJson(
          _json["entityFilter"]);
    }
    if (_json.containsKey("outputUrlPrefix")) {
      outputUrlPrefix = _json["outputUrlPrefix"];
    }
    if (_json.containsKey("progressBytes")) {
      progressBytes = new GoogleDatastoreAdminV1beta1Progress.fromJson(
          _json["progressBytes"]);
    }
    if (_json.containsKey("progressEntities")) {
      progressEntities = new GoogleDatastoreAdminV1beta1Progress.fromJson(
          _json["progressEntities"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (common != null) {
      _json["common"] = (common).toJson();
    }
    if (entityFilter != null) {
      _json["entityFilter"] = (entityFilter).toJson();
    }
    if (outputUrlPrefix != null) {
      _json["outputUrlPrefix"] = outputUrlPrefix;
    }
    if (progressBytes != null) {
      _json["progressBytes"] = (progressBytes).toJson();
    }
    if (progressEntities != null) {
      _json["progressEntities"] = (progressEntities).toJson();
    }
    return _json;
  }
}

/// The response for
/// google.datastore.admin.v1beta1.DatastoreAdmin.ExportEntities.
class GoogleDatastoreAdminV1beta1ExportEntitiesResponse {
  /// Location of the output metadata file. This can be used to begin an import
  /// into Cloud Datastore (this project or another project). See
  /// google.datastore.admin.v1beta1.ImportEntitiesRequest.input_url.
  /// Only present if the operation completed successfully.
  core.String outputUrl;

  GoogleDatastoreAdminV1beta1ExportEntitiesResponse();

  GoogleDatastoreAdminV1beta1ExportEntitiesResponse.fromJson(core.Map _json) {
    if (_json.containsKey("outputUrl")) {
      outputUrl = _json["outputUrl"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (outputUrl != null) {
      _json["outputUrl"] = outputUrl;
    }
    return _json;
  }
}

/// Metadata for ImportEntities operations.
class GoogleDatastoreAdminV1beta1ImportEntitiesMetadata {
  /// Metadata common to all Datastore Admin operations.
  GoogleDatastoreAdminV1beta1CommonMetadata common;

  /// Description of which entities are being imported.
  GoogleDatastoreAdminV1beta1EntityFilter entityFilter;

  /// The location of the import metadata file. This will be the same value as
  /// the google.datastore.admin.v1beta1.ExportEntitiesResponse.output_url
  /// field.
  core.String inputUrl;

  /// An estimate of the number of bytes processed.
  GoogleDatastoreAdminV1beta1Progress progressBytes;

  /// An estimate of the number of entities processed.
  GoogleDatastoreAdminV1beta1Progress progressEntities;

  GoogleDatastoreAdminV1beta1ImportEntitiesMetadata();

  GoogleDatastoreAdminV1beta1ImportEntitiesMetadata.fromJson(core.Map _json) {
    if (_json.containsKey("common")) {
      common = new GoogleDatastoreAdminV1beta1CommonMetadata.fromJson(
          _json["common"]);
    }
    if (_json.containsKey("entityFilter")) {
      entityFilter = new GoogleDatastoreAdminV1beta1EntityFilter.fromJson(
          _json["entityFilter"]);
    }
    if (_json.containsKey("inputUrl")) {
      inputUrl = _json["inputUrl"];
    }
    if (_json.containsKey("progressBytes")) {
      progressBytes = new GoogleDatastoreAdminV1beta1Progress.fromJson(
          _json["progressBytes"]);
    }
    if (_json.containsKey("progressEntities")) {
      progressEntities = new GoogleDatastoreAdminV1beta1Progress.fromJson(
          _json["progressEntities"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (common != null) {
      _json["common"] = (common).toJson();
    }
    if (entityFilter != null) {
      _json["entityFilter"] = (entityFilter).toJson();
    }
    if (inputUrl != null) {
      _json["inputUrl"] = inputUrl;
    }
    if (progressBytes != null) {
      _json["progressBytes"] = (progressBytes).toJson();
    }
    if (progressEntities != null) {
      _json["progressEntities"] = (progressEntities).toJson();
    }
    return _json;
  }
}

/// Measures the progress of a particular metric.
class GoogleDatastoreAdminV1beta1Progress {
  /// The amount of work that has been completed. Note that this may be greater
  /// than work_estimated.
  core.String workCompleted;

  /// An estimate of how much work needs to be performed. May be zero if the
  /// work estimate is unavailable.
  core.String workEstimated;

  GoogleDatastoreAdminV1beta1Progress();

  GoogleDatastoreAdminV1beta1Progress.fromJson(core.Map _json) {
    if (_json.containsKey("workCompleted")) {
      workCompleted = _json["workCompleted"];
    }
    if (_json.containsKey("workEstimated")) {
      workEstimated = _json["workEstimated"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (workCompleted != null) {
      _json["workCompleted"] = workCompleted;
    }
    if (workEstimated != null) {
      _json["workEstimated"] = workEstimated;
    }
    return _json;
  }
}

/// The response message for Operations.ListOperations.
class GoogleLongrunningListOperationsResponse {
  /// The standard List next-page token.
  core.String nextPageToken;

  /// A list of operations that matches the specified filter in the request.
  core.List<GoogleLongrunningOperation> operations;

  GoogleLongrunningListOperationsResponse();

  GoogleLongrunningListOperationsResponse.fromJson(core.Map _json) {
    if (_json.containsKey("nextPageToken")) {
      nextPageToken = _json["nextPageToken"];
    }
    if (_json.containsKey("operations")) {
      operations = _json["operations"]
          .map((value) => new GoogleLongrunningOperation.fromJson(value))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (nextPageToken != null) {
      _json["nextPageToken"] = nextPageToken;
    }
    if (operations != null) {
      _json["operations"] =
          operations.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// This resource represents a long-running operation that is the result of a
/// network API call.
class GoogleLongrunningOperation {
  /// If the value is `false`, it means the operation is still in progress.
  /// If `true`, the operation is completed, and either `error` or `response` is
  /// available.
  core.bool done;

  /// The error result of the operation in case of failure or cancellation.
  Status error;

  /// Service-specific metadata associated with the operation.  It typically
  /// contains progress information and common metadata such as create time.
  /// Some services might not provide such metadata.  Any method that returns a
  /// long-running operation should document the metadata type, if any.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.Map<core.String, core.Object> metadata;

  /// The server-assigned name, which is only unique within the same service
  /// that
  /// originally returns it. If you use the default HTTP mapping, the
  /// `name` should have the format of `operations/some/unique/name`.
  core.String name;

  /// The normal response of the operation in case of success.  If the original
  /// method returns no data on success, such as `Delete`, the response is
  /// `google.protobuf.Empty`.  If the original method is standard
  /// `Get`/`Create`/`Update`, the response should be the resource.  For other
  /// methods, the response should have the type `XxxResponse`, where `Xxx`
  /// is the original method name.  For example, if the original method name
  /// is `TakeSnapshot()`, the inferred response type is
  /// `TakeSnapshotResponse`.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.Map<core.String, core.Object> response;

  GoogleLongrunningOperation();

  GoogleLongrunningOperation.fromJson(core.Map _json) {
    if (_json.containsKey("done")) {
      done = _json["done"];
    }
    if (_json.containsKey("error")) {
      error = new Status.fromJson(_json["error"]);
    }
    if (_json.containsKey("metadata")) {
      metadata = _json["metadata"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("response")) {
      response = _json["response"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (done != null) {
      _json["done"] = done;
    }
    if (error != null) {
      _json["error"] = (error).toJson();
    }
    if (metadata != null) {
      _json["metadata"] = metadata;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (response != null) {
      _json["response"] = response;
    }
    return _json;
  }
}

/// A [GQL
/// query](https://cloud.google.com/datastore/docs/apis/gql/gql_reference).
class GqlQuery {
  /// When false, the query string must not contain any literals and instead
  /// must
  /// bind all values. For example,
  /// `SELECT * FROM Kind WHERE a = 'string literal'` is not allowed, while
  /// `SELECT * FROM Kind WHERE a = @value` is.
  core.bool allowLiterals;

  /// For each non-reserved named binding site in the query string, there must
  /// be
  /// a named parameter with that name, but not necessarily the inverse.
  ///
  /// Key must match regex `A-Za-z_$*`, must not match regex
  /// `__.*__`, and must not be `""`.
  core.Map<core.String, GqlQueryParameter> namedBindings;

  /// Numbered binding site @1 references the first numbered parameter,
  /// effectively using 1-based indexing, rather than the usual 0.
  ///
  /// For each binding site numbered i in `query_string`, there must be an i-th
  /// numbered parameter. The inverse must also be true.
  core.List<GqlQueryParameter> positionalBindings;

  /// A string of the format described
  /// [here](https://cloud.google.com/datastore/docs/apis/gql/gql_reference).
  core.String queryString;

  GqlQuery();

  GqlQuery.fromJson(core.Map _json) {
    if (_json.containsKey("allowLiterals")) {
      allowLiterals = _json["allowLiterals"];
    }
    if (_json.containsKey("namedBindings")) {
      namedBindings =
          commons.mapMap<core.Map<core.String, core.Object>, GqlQueryParameter>(
              _json["namedBindings"],
              (core.Map<core.String, core.Object> item) =>
                  new GqlQueryParameter.fromJson(item));
    }
    if (_json.containsKey("positionalBindings")) {
      positionalBindings = _json["positionalBindings"]
          .map((value) => new GqlQueryParameter.fromJson(value))
          .toList();
    }
    if (_json.containsKey("queryString")) {
      queryString = _json["queryString"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (allowLiterals != null) {
      _json["allowLiterals"] = allowLiterals;
    }
    if (namedBindings != null) {
      _json["namedBindings"] =
          commons.mapMap<GqlQueryParameter, core.Map<core.String, core.Object>>(
              namedBindings, (GqlQueryParameter item) => (item).toJson());
    }
    if (positionalBindings != null) {
      _json["positionalBindings"] =
          positionalBindings.map((value) => (value).toJson()).toList();
    }
    if (queryString != null) {
      _json["queryString"] = queryString;
    }
    return _json;
  }
}

/// A binding parameter for a GQL query.
class GqlQueryParameter {
  /// A query cursor. Query cursors are returned in query
  /// result batches.
  core.String cursor;
  core.List<core.int> get cursorAsBytes {
    return convert.BASE64.decode(cursor);
  }

  void set cursorAsBytes(core.List<core.int> _bytes) {
    cursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// A value parameter.
  Value value;

  GqlQueryParameter();

  GqlQueryParameter.fromJson(core.Map _json) {
    if (_json.containsKey("cursor")) {
      cursor = _json["cursor"];
    }
    if (_json.containsKey("value")) {
      value = new Value.fromJson(_json["value"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (cursor != null) {
      _json["cursor"] = cursor;
    }
    if (value != null) {
      _json["value"] = (value).toJson();
    }
    return _json;
  }
}

/// A unique identifier for an entity.
/// If a key's partition ID or any of its path kinds or names are
/// reserved/read-only, the key is reserved/read-only.
/// A reserved/read-only key is forbidden in certain documented contexts.
class Key {
  /// Entities are partitioned into subsets, currently identified by a project
  /// ID and namespace ID.
  /// Queries are scoped to a single partition.
  PartitionId partitionId;

  /// The entity path.
  /// An entity path consists of one or more elements composed of a kind and a
  /// string or numerical identifier, which identify entities. The first
  /// element identifies a _root entity_, the second element identifies
  /// a _child_ of the root entity, the third element identifies a child of the
  /// second entity, and so forth. The entities identified by all prefixes of
  /// the path are called the element's _ancestors_.
  ///
  /// An entity path is always fully complete: *all* of the entity's ancestors
  /// are required to be in the path along with the entity identifier itself.
  /// The only exception is that in some documented cases, the identifier in the
  /// last path element (for the entity) itself may be omitted. For example,
  /// the last path element of the key of `Mutation.insert` may have no
  /// identifier.
  ///
  /// A path can never be empty, and a path can have at most 100 elements.
  core.List<PathElement> path;

  Key();

  Key.fromJson(core.Map _json) {
    if (_json.containsKey("partitionId")) {
      partitionId = new PartitionId.fromJson(_json["partitionId"]);
    }
    if (_json.containsKey("path")) {
      path = _json["path"]
          .map((value) => new PathElement.fromJson(value))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (partitionId != null) {
      _json["partitionId"] = (partitionId).toJson();
    }
    if (path != null) {
      _json["path"] = path.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// A representation of a kind.
class KindExpression {
  /// The name of the kind.
  core.String name;

  KindExpression();

  KindExpression.fromJson(core.Map _json) {
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}

/// An object representing a latitude/longitude pair. This is expressed as a
/// pair
/// of doubles representing degrees latitude and degrees longitude. Unless
/// specified otherwise, this must conform to the
/// <a href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
/// standard</a>. Values must be within normalized ranges.
class LatLng {
  /// The latitude in degrees. It must be in the range [-90.0, +90.0].
  core.double latitude;

  /// The longitude in degrees. It must be in the range [-180.0, +180.0].
  core.double longitude;

  LatLng();

  LatLng.fromJson(core.Map _json) {
    if (_json.containsKey("latitude")) {
      latitude = _json["latitude"];
    }
    if (_json.containsKey("longitude")) {
      longitude = _json["longitude"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (latitude != null) {
      _json["latitude"] = latitude;
    }
    if (longitude != null) {
      _json["longitude"] = longitude;
    }
    return _json;
  }
}

/// The request for Datastore.Lookup.
class LookupRequest {
  /// Keys of entities to look up.
  core.List<Key> keys;

  /// The options for this lookup request.
  ReadOptions readOptions;

  LookupRequest();

  LookupRequest.fromJson(core.Map _json) {
    if (_json.containsKey("keys")) {
      keys = _json["keys"].map((value) => new Key.fromJson(value)).toList();
    }
    if (_json.containsKey("readOptions")) {
      readOptions = new ReadOptions.fromJson(_json["readOptions"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (keys != null) {
      _json["keys"] = keys.map((value) => (value).toJson()).toList();
    }
    if (readOptions != null) {
      _json["readOptions"] = (readOptions).toJson();
    }
    return _json;
  }
}

/// The response for Datastore.Lookup.
class LookupResponse {
  /// A list of keys that were not looked up due to resource constraints. The
  /// order of results in this field is undefined and has no relation to the
  /// order of the keys in the input.
  core.List<Key> deferred;

  /// Entities found as `ResultType.FULL` entities. The order of results in this
  /// field is undefined and has no relation to the order of the keys in the
  /// input.
  core.List<EntityResult> found;

  /// Entities not found as `ResultType.KEY_ONLY` entities. The order of results
  /// in this field is undefined and has no relation to the order of the keys
  /// in the input.
  core.List<EntityResult> missing;

  LookupResponse();

  LookupResponse.fromJson(core.Map _json) {
    if (_json.containsKey("deferred")) {
      deferred =
          _json["deferred"].map((value) => new Key.fromJson(value)).toList();
    }
    if (_json.containsKey("found")) {
      found = _json["found"]
          .map((value) => new EntityResult.fromJson(value))
          .toList();
    }
    if (_json.containsKey("missing")) {
      missing = _json["missing"]
          .map((value) => new EntityResult.fromJson(value))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (deferred != null) {
      _json["deferred"] = deferred.map((value) => (value).toJson()).toList();
    }
    if (found != null) {
      _json["found"] = found.map((value) => (value).toJson()).toList();
    }
    if (missing != null) {
      _json["missing"] = missing.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// A mutation to apply to an entity.
class Mutation {
  /// The version of the entity that this mutation is being applied to. If this
  /// does not match the current version on the server, the mutation conflicts.
  core.String baseVersion;

  /// The key of the entity to delete. The entity may or may not already exist.
  /// Must have a complete key path and must not be reserved/read-only.
  Key delete;

  /// The entity to insert. The entity must not already exist.
  /// The entity key's final path element may be incomplete.
  Entity insert;

  /// The entity to update. The entity must already exist.
  /// Must have a complete key path.
  Entity update;

  /// The entity to upsert. The entity may or may not already exist.
  /// The entity key's final path element may be incomplete.
  Entity upsert;

  Mutation();

  Mutation.fromJson(core.Map _json) {
    if (_json.containsKey("baseVersion")) {
      baseVersion = _json["baseVersion"];
    }
    if (_json.containsKey("delete")) {
      delete = new Key.fromJson(_json["delete"]);
    }
    if (_json.containsKey("insert")) {
      insert = new Entity.fromJson(_json["insert"]);
    }
    if (_json.containsKey("update")) {
      update = new Entity.fromJson(_json["update"]);
    }
    if (_json.containsKey("upsert")) {
      upsert = new Entity.fromJson(_json["upsert"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (baseVersion != null) {
      _json["baseVersion"] = baseVersion;
    }
    if (delete != null) {
      _json["delete"] = (delete).toJson();
    }
    if (insert != null) {
      _json["insert"] = (insert).toJson();
    }
    if (update != null) {
      _json["update"] = (update).toJson();
    }
    if (upsert != null) {
      _json["upsert"] = (upsert).toJson();
    }
    return _json;
  }
}

/// The result of applying a mutation.
class MutationResult {
  /// Whether a conflict was detected for this mutation. Always false when a
  /// conflict detection strategy field is not set in the mutation.
  core.bool conflictDetected;

  /// The automatically allocated key.
  /// Set only when the mutation allocated a key.
  Key key;

  /// The version of the entity on the server after processing the mutation. If
  /// the mutation doesn't change anything on the server, then the version will
  /// be the version of the current entity or, if no entity is present, a
  /// version
  /// that is strictly greater than the version of any previous entity and less
  /// than the version of any possible future entity.
  core.String version;

  MutationResult();

  MutationResult.fromJson(core.Map _json) {
    if (_json.containsKey("conflictDetected")) {
      conflictDetected = _json["conflictDetected"];
    }
    if (_json.containsKey("key")) {
      key = new Key.fromJson(_json["key"]);
    }
    if (_json.containsKey("version")) {
      version = _json["version"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (conflictDetected != null) {
      _json["conflictDetected"] = conflictDetected;
    }
    if (key != null) {
      _json["key"] = (key).toJson();
    }
    if (version != null) {
      _json["version"] = version;
    }
    return _json;
  }
}

/// A partition ID identifies a grouping of entities. The grouping is always
/// by project and namespace, however the namespace ID may be empty.
///
/// A partition ID contains several dimensions:
/// project ID and namespace ID.
///
/// Partition dimensions:
///
/// - May be `""`.
/// - Must be valid UTF-8 bytes.
/// - Must have values that match regex `[A-Za-z\d\.\-_]{1,100}`
/// If the value of any dimension matches regex `__.*__`, the partition is
/// reserved/read-only.
/// A reserved/read-only partition ID is forbidden in certain documented
/// contexts.
///
/// Foreign partition IDs (in which the project ID does
/// not match the context project ID ) are discouraged.
/// Reads and writes of foreign partition IDs may fail if the project is not in
/// an active state.
class PartitionId {
  /// If not empty, the ID of the namespace to which the entities belong.
  core.String namespaceId;

  /// The ID of the project to which the entities belong.
  core.String projectId;

  PartitionId();

  PartitionId.fromJson(core.Map _json) {
    if (_json.containsKey("namespaceId")) {
      namespaceId = _json["namespaceId"];
    }
    if (_json.containsKey("projectId")) {
      projectId = _json["projectId"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (namespaceId != null) {
      _json["namespaceId"] = namespaceId;
    }
    if (projectId != null) {
      _json["projectId"] = projectId;
    }
    return _json;
  }
}

/// A (kind, ID/name) pair used to construct a key path.
///
/// If either name or ID is set, the element is complete.
/// If neither is set, the element is incomplete.
class PathElement {
  /// The auto-allocated ID of the entity.
  /// Never equal to zero. Values less than zero are discouraged and may not
  /// be supported in the future.
  core.String id;

  /// The kind of the entity.
  /// A kind matching regex `__.*__` is reserved/read-only.
  /// A kind must not contain more than 1500 bytes when UTF-8 encoded.
  /// Cannot be `""`.
  core.String kind;

  /// The name of the entity.
  /// A name matching regex `__.*__` is reserved/read-only.
  /// A name must not be more than 1500 bytes when UTF-8 encoded.
  /// Cannot be `""`.
  core.String name;

  PathElement();

  PathElement.fromJson(core.Map _json) {
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}

/// A representation of a property in a projection.
class Projection {
  /// The property to project.
  PropertyReference property;

  Projection();

  Projection.fromJson(core.Map _json) {
    if (_json.containsKey("property")) {
      property = new PropertyReference.fromJson(_json["property"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (property != null) {
      _json["property"] = (property).toJson();
    }
    return _json;
  }
}

/// A filter on a specific property.
class PropertyFilter {
  /// The operator to filter by.
  /// Possible string values are:
  /// - "OPERATOR_UNSPECIFIED" : Unspecified. This value must not be used.
  /// - "LESS_THAN" : Less than.
  /// - "LESS_THAN_OR_EQUAL" : Less than or equal.
  /// - "GREATER_THAN" : Greater than.
  /// - "GREATER_THAN_OR_EQUAL" : Greater than or equal.
  /// - "EQUAL" : Equal.
  /// - "HAS_ANCESTOR" : Has ancestor.
  core.String op;

  /// The property to filter by.
  PropertyReference property;

  /// The value to compare the property to.
  Value value;

  PropertyFilter();

  PropertyFilter.fromJson(core.Map _json) {
    if (_json.containsKey("op")) {
      op = _json["op"];
    }
    if (_json.containsKey("property")) {
      property = new PropertyReference.fromJson(_json["property"]);
    }
    if (_json.containsKey("value")) {
      value = new Value.fromJson(_json["value"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (op != null) {
      _json["op"] = op;
    }
    if (property != null) {
      _json["property"] = (property).toJson();
    }
    if (value != null) {
      _json["value"] = (value).toJson();
    }
    return _json;
  }
}

/// The desired order for a specific property.
class PropertyOrder {
  /// The direction to order by. Defaults to `ASCENDING`.
  /// Possible string values are:
  /// - "DIRECTION_UNSPECIFIED" : Unspecified. This value must not be used.
  /// - "ASCENDING" : Ascending.
  /// - "DESCENDING" : Descending.
  core.String direction;

  /// The property to order by.
  PropertyReference property;

  PropertyOrder();

  PropertyOrder.fromJson(core.Map _json) {
    if (_json.containsKey("direction")) {
      direction = _json["direction"];
    }
    if (_json.containsKey("property")) {
      property = new PropertyReference.fromJson(_json["property"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (direction != null) {
      _json["direction"] = direction;
    }
    if (property != null) {
      _json["property"] = (property).toJson();
    }
    return _json;
  }
}

/// A reference to a property relative to the kind expressions.
class PropertyReference {
  /// The name of the property.
  /// If name includes "."s, it may be interpreted as a property name path.
  core.String name;

  PropertyReference();

  PropertyReference.fromJson(core.Map _json) {
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}

/// A query for entities.
class Query {
  /// The properties to make distinct. The query results will contain the first
  /// result for each distinct combination of values for the given properties
  /// (if empty, all results are returned).
  core.List<PropertyReference> distinctOn;

  /// An ending point for the query results. Query cursors are
  /// returned in query result batches and
  /// [can only be used to limit the same
  /// query](https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets).
  core.String endCursor;
  core.List<core.int> get endCursorAsBytes {
    return convert.BASE64.decode(endCursor);
  }

  void set endCursorAsBytes(core.List<core.int> _bytes) {
    endCursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// The filter to apply.
  Filter filter;

  /// The kinds to query (if empty, returns entities of all kinds).
  /// Currently at most 1 kind may be specified.
  core.List<KindExpression> kind;

  /// The maximum number of results to return. Applies after all other
  /// constraints. Optional.
  /// Unspecified is interpreted as no limit.
  /// Must be >= 0 if specified.
  core.int limit;

  /// The number of results to skip. Applies before limit, but after all other
  /// constraints. Optional. Must be >= 0 if specified.
  core.int offset;

  /// The order to apply to the query results (if empty, order is unspecified).
  core.List<PropertyOrder> order;

  /// The projection to return. Defaults to returning all properties.
  core.List<Projection> projection;

  /// A starting point for the query results. Query cursors are
  /// returned in query result batches and
  /// [can only be used to continue the same
  /// query](https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets).
  core.String startCursor;
  core.List<core.int> get startCursorAsBytes {
    return convert.BASE64.decode(startCursor);
  }

  void set startCursorAsBytes(core.List<core.int> _bytes) {
    startCursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  Query();

  Query.fromJson(core.Map _json) {
    if (_json.containsKey("distinctOn")) {
      distinctOn = _json["distinctOn"]
          .map((value) => new PropertyReference.fromJson(value))
          .toList();
    }
    if (_json.containsKey("endCursor")) {
      endCursor = _json["endCursor"];
    }
    if (_json.containsKey("filter")) {
      filter = new Filter.fromJson(_json["filter"]);
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"]
          .map((value) => new KindExpression.fromJson(value))
          .toList();
    }
    if (_json.containsKey("limit")) {
      limit = _json["limit"];
    }
    if (_json.containsKey("offset")) {
      offset = _json["offset"];
    }
    if (_json.containsKey("order")) {
      order = _json["order"]
          .map((value) => new PropertyOrder.fromJson(value))
          .toList();
    }
    if (_json.containsKey("projection")) {
      projection = _json["projection"]
          .map((value) => new Projection.fromJson(value))
          .toList();
    }
    if (_json.containsKey("startCursor")) {
      startCursor = _json["startCursor"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (distinctOn != null) {
      _json["distinctOn"] =
          distinctOn.map((value) => (value).toJson()).toList();
    }
    if (endCursor != null) {
      _json["endCursor"] = endCursor;
    }
    if (filter != null) {
      _json["filter"] = (filter).toJson();
    }
    if (kind != null) {
      _json["kind"] = kind.map((value) => (value).toJson()).toList();
    }
    if (limit != null) {
      _json["limit"] = limit;
    }
    if (offset != null) {
      _json["offset"] = offset;
    }
    if (order != null) {
      _json["order"] = order.map((value) => (value).toJson()).toList();
    }
    if (projection != null) {
      _json["projection"] =
          projection.map((value) => (value).toJson()).toList();
    }
    if (startCursor != null) {
      _json["startCursor"] = startCursor;
    }
    return _json;
  }
}

/// A batch of results produced by a query.
class QueryResultBatch {
  /// A cursor that points to the position after the last result in the batch.
  core.String endCursor;
  core.List<core.int> get endCursorAsBytes {
    return convert.BASE64.decode(endCursor);
  }

  void set endCursorAsBytes(core.List<core.int> _bytes) {
    endCursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// The result type for every entity in `entity_results`.
  /// Possible string values are:
  /// - "RESULT_TYPE_UNSPECIFIED" : Unspecified. This value is never used.
  /// - "FULL" : The key and properties.
  /// - "PROJECTION" : A projected subset of properties. The entity may have no
  /// key.
  /// - "KEY_ONLY" : Only the key.
  core.String entityResultType;

  /// The results for this batch.
  core.List<EntityResult> entityResults;

  /// The state of the query after the current batch.
  /// Possible string values are:
  /// - "MORE_RESULTS_TYPE_UNSPECIFIED" : Unspecified. This value is never used.
  /// - "NOT_FINISHED" : There may be additional batches to fetch from this
  /// query.
  /// - "MORE_RESULTS_AFTER_LIMIT" : The query is finished, but there may be
  /// more results after the limit.
  /// - "MORE_RESULTS_AFTER_CURSOR" : The query is finished, but there may be
  /// more results after the end
  /// cursor.
  /// - "NO_MORE_RESULTS" : The query is finished, and there are no more
  /// results.
  core.String moreResults;

  /// A cursor that points to the position after the last skipped result.
  /// Will be set when `skipped_results` != 0.
  core.String skippedCursor;
  core.List<core.int> get skippedCursorAsBytes {
    return convert.BASE64.decode(skippedCursor);
  }

  void set skippedCursorAsBytes(core.List<core.int> _bytes) {
    skippedCursor =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// The number of results skipped, typically because of an offset.
  core.int skippedResults;

  /// The version number of the snapshot this batch was returned from.
  /// This applies to the range of results from the query's `start_cursor` (or
  /// the beginning of the query if no cursor was given) to this batch's
  /// `end_cursor` (not the query's `end_cursor`).
  ///
  /// In a single transaction, subsequent query result batches for the same
  /// query
  /// can have a greater snapshot version number. Each batch's snapshot version
  /// is valid for all preceding batches.
  /// The value will be zero for eventually consistent queries.
  core.String snapshotVersion;

  QueryResultBatch();

  QueryResultBatch.fromJson(core.Map _json) {
    if (_json.containsKey("endCursor")) {
      endCursor = _json["endCursor"];
    }
    if (_json.containsKey("entityResultType")) {
      entityResultType = _json["entityResultType"];
    }
    if (_json.containsKey("entityResults")) {
      entityResults = _json["entityResults"]
          .map((value) => new EntityResult.fromJson(value))
          .toList();
    }
    if (_json.containsKey("moreResults")) {
      moreResults = _json["moreResults"];
    }
    if (_json.containsKey("skippedCursor")) {
      skippedCursor = _json["skippedCursor"];
    }
    if (_json.containsKey("skippedResults")) {
      skippedResults = _json["skippedResults"];
    }
    if (_json.containsKey("snapshotVersion")) {
      snapshotVersion = _json["snapshotVersion"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (endCursor != null) {
      _json["endCursor"] = endCursor;
    }
    if (entityResultType != null) {
      _json["entityResultType"] = entityResultType;
    }
    if (entityResults != null) {
      _json["entityResults"] =
          entityResults.map((value) => (value).toJson()).toList();
    }
    if (moreResults != null) {
      _json["moreResults"] = moreResults;
    }
    if (skippedCursor != null) {
      _json["skippedCursor"] = skippedCursor;
    }
    if (skippedResults != null) {
      _json["skippedResults"] = skippedResults;
    }
    if (snapshotVersion != null) {
      _json["snapshotVersion"] = snapshotVersion;
    }
    return _json;
  }
}

/// Options specific to read-only transactions.
class ReadOnly {
  ReadOnly();

  ReadOnly.fromJson(core.Map _json) {}

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    return _json;
  }
}

/// The options shared by read requests.
class ReadOptions {
  /// The non-transactional read consistency to use.
  /// Cannot be set to `STRONG` for global queries.
  /// Possible string values are:
  /// - "READ_CONSISTENCY_UNSPECIFIED" : Unspecified. This value must not be
  /// used.
  /// - "STRONG" : Strong consistency.
  /// - "EVENTUAL" : Eventual consistency.
  core.String readConsistency;

  /// The identifier of the transaction in which to read. A
  /// transaction identifier is returned by a call to
  /// Datastore.BeginTransaction.
  core.String transaction;
  core.List<core.int> get transactionAsBytes {
    return convert.BASE64.decode(transaction);
  }

  void set transactionAsBytes(core.List<core.int> _bytes) {
    transaction =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  ReadOptions();

  ReadOptions.fromJson(core.Map _json) {
    if (_json.containsKey("readConsistency")) {
      readConsistency = _json["readConsistency"];
    }
    if (_json.containsKey("transaction")) {
      transaction = _json["transaction"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (readConsistency != null) {
      _json["readConsistency"] = readConsistency;
    }
    if (transaction != null) {
      _json["transaction"] = transaction;
    }
    return _json;
  }
}

/// Options specific to read / write transactions.
class ReadWrite {
  /// The transaction identifier of the transaction being retried.
  core.String previousTransaction;
  core.List<core.int> get previousTransactionAsBytes {
    return convert.BASE64.decode(previousTransaction);
  }

  void set previousTransactionAsBytes(core.List<core.int> _bytes) {
    previousTransaction =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  ReadWrite();

  ReadWrite.fromJson(core.Map _json) {
    if (_json.containsKey("previousTransaction")) {
      previousTransaction = _json["previousTransaction"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (previousTransaction != null) {
      _json["previousTransaction"] = previousTransaction;
    }
    return _json;
  }
}

/// The request for Datastore.ReserveIds.
class ReserveIdsRequest {
  /// If not empty, the ID of the database against which to make the request.
  core.String databaseId;

  /// A list of keys with complete key paths whose numeric IDs should not be
  /// auto-allocated.
  core.List<Key> keys;

  ReserveIdsRequest();

  ReserveIdsRequest.fromJson(core.Map _json) {
    if (_json.containsKey("databaseId")) {
      databaseId = _json["databaseId"];
    }
    if (_json.containsKey("keys")) {
      keys = _json["keys"].map((value) => new Key.fromJson(value)).toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (databaseId != null) {
      _json["databaseId"] = databaseId;
    }
    if (keys != null) {
      _json["keys"] = keys.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}

/// The response for Datastore.ReserveIds.
class ReserveIdsResponse {
  ReserveIdsResponse();

  ReserveIdsResponse.fromJson(core.Map _json) {}

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    return _json;
  }
}

/// The request for Datastore.Rollback.
class RollbackRequest {
  /// The transaction identifier, returned by a call to
  /// Datastore.BeginTransaction.
  core.String transaction;
  core.List<core.int> get transactionAsBytes {
    return convert.BASE64.decode(transaction);
  }

  void set transactionAsBytes(core.List<core.int> _bytes) {
    transaction =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  RollbackRequest();

  RollbackRequest.fromJson(core.Map _json) {
    if (_json.containsKey("transaction")) {
      transaction = _json["transaction"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (transaction != null) {
      _json["transaction"] = transaction;
    }
    return _json;
  }
}

/// The response for Datastore.Rollback.
/// (an empty message).
class RollbackResponse {
  RollbackResponse();

  RollbackResponse.fromJson(core.Map _json) {}

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    return _json;
  }
}

/// The request for Datastore.RunQuery.
class RunQueryRequest {
  /// The GQL query to run.
  GqlQuery gqlQuery;

  /// Entities are partitioned into subsets, identified by a partition ID.
  /// Queries are scoped to a single partition.
  /// This partition ID is normalized with the standard default context
  /// partition ID.
  PartitionId partitionId;

  /// The query to run.
  Query query;

  /// The options for this query.
  ReadOptions readOptions;

  RunQueryRequest();

  RunQueryRequest.fromJson(core.Map _json) {
    if (_json.containsKey("gqlQuery")) {
      gqlQuery = new GqlQuery.fromJson(_json["gqlQuery"]);
    }
    if (_json.containsKey("partitionId")) {
      partitionId = new PartitionId.fromJson(_json["partitionId"]);
    }
    if (_json.containsKey("query")) {
      query = new Query.fromJson(_json["query"]);
    }
    if (_json.containsKey("readOptions")) {
      readOptions = new ReadOptions.fromJson(_json["readOptions"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (gqlQuery != null) {
      _json["gqlQuery"] = (gqlQuery).toJson();
    }
    if (partitionId != null) {
      _json["partitionId"] = (partitionId).toJson();
    }
    if (query != null) {
      _json["query"] = (query).toJson();
    }
    if (readOptions != null) {
      _json["readOptions"] = (readOptions).toJson();
    }
    return _json;
  }
}

/// The response for Datastore.RunQuery.
class RunQueryResponse {
  /// A batch of query results (always present).
  QueryResultBatch batch;

  /// The parsed form of the `GqlQuery` from the request, if it was set.
  Query query;

  RunQueryResponse();

  RunQueryResponse.fromJson(core.Map _json) {
    if (_json.containsKey("batch")) {
      batch = new QueryResultBatch.fromJson(_json["batch"]);
    }
    if (_json.containsKey("query")) {
      query = new Query.fromJson(_json["query"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (batch != null) {
      _json["batch"] = (batch).toJson();
    }
    if (query != null) {
      _json["query"] = (query).toJson();
    }
    return _json;
  }
}

/// The `Status` type defines a logical error model that is suitable for
/// different
/// programming environments, including REST APIs and RPC APIs. It is used by
/// [gRPC](https://github.com/grpc). The error model is designed to be:
///
/// - Simple to use and understand for most users
/// - Flexible enough to meet unexpected needs
///
/// # Overview
///
/// The `Status` message contains three pieces of data: error code, error
/// message,
/// and error details. The error code should be an enum value of
/// google.rpc.Code, but it may accept additional error codes if needed.  The
/// error message should be a developer-facing English message that helps
/// developers *understand* and *resolve* the error. If a localized user-facing
/// error message is needed, put the localized message in the error details or
/// localize it in the client. The optional error details may contain arbitrary
/// information about the error. There is a predefined set of error detail types
/// in the package `google.rpc` that can be used for common error conditions.
///
/// # Language mapping
///
/// The `Status` message is the logical representation of the error model, but
/// it
/// is not necessarily the actual wire format. When the `Status` message is
/// exposed in different client libraries and different wire protocols, it can
/// be
/// mapped differently. For example, it will likely be mapped to some exceptions
/// in Java, but more likely mapped to some error codes in C.
///
/// # Other uses
///
/// The error model and the `Status` message can be used in a variety of
/// environments, either with or without APIs, to provide a
/// consistent developer experience across different environments.
///
/// Example uses of this error model include:
///
/// - Partial errors. If a service needs to return partial errors to the client,
/// it may embed the `Status` in the normal response to indicate the partial
///     errors.
///
/// - Workflow errors. A typical workflow has multiple steps. Each step may
///     have a `Status` message for error reporting.
///
/// - Batch operations. If a client uses batch request and batch response, the
///     `Status` message should be used directly inside batch response, one for
///     each error sub-response.
///
/// - Asynchronous operations. If an API call embeds asynchronous operation
///     results in its response, the status of those operations should be
///     represented directly using the `Status` message.
///
/// - Logging. If some API errors are stored in logs, the message `Status` could
/// be used directly after any stripping needed for security/privacy reasons.
class Status {
  /// The status code, which should be an enum value of google.rpc.Code.
  core.int code;

  /// A list of messages that carry the error details.  There is a common set of
  /// message types for APIs to use.
  ///
  /// The values for Object must be JSON objects. It can consist of `num`,
  /// `String`, `bool` and `null` as well as `Map` and `List` values.
  core.List<core.Map<core.String, core.Object>> details;

  /// A developer-facing error message, which should be in English. Any
  /// user-facing error message should be localized and sent in the
  /// google.rpc.Status.details field, or localized by the client.
  core.String message;

  Status();

  Status.fromJson(core.Map _json) {
    if (_json.containsKey("code")) {
      code = _json["code"];
    }
    if (_json.containsKey("details")) {
      details = _json["details"];
    }
    if (_json.containsKey("message")) {
      message = _json["message"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (code != null) {
      _json["code"] = code;
    }
    if (details != null) {
      _json["details"] = details;
    }
    if (message != null) {
      _json["message"] = message;
    }
    return _json;
  }
}

/// Options for beginning a new transaction.
///
/// Transactions can be created explicitly with calls to
/// Datastore.BeginTransaction or implicitly by setting
/// ReadOptions.new_transaction in read requests.
class TransactionOptions {
  /// The transaction should only allow reads.
  ReadOnly readOnly;

  /// The transaction should allow both reads and writes.
  ReadWrite readWrite;

  TransactionOptions();

  TransactionOptions.fromJson(core.Map _json) {
    if (_json.containsKey("readOnly")) {
      readOnly = new ReadOnly.fromJson(_json["readOnly"]);
    }
    if (_json.containsKey("readWrite")) {
      readWrite = new ReadWrite.fromJson(_json["readWrite"]);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (readOnly != null) {
      _json["readOnly"] = (readOnly).toJson();
    }
    if (readWrite != null) {
      _json["readWrite"] = (readWrite).toJson();
    }
    return _json;
  }
}

/// A message that can hold any of the supported value types and associated
/// metadata.
class Value {
  /// An array value.
  /// Cannot contain another array value.
  /// A `Value` instance that sets field `array_value` must not set fields
  /// `meaning` or `exclude_from_indexes`.
  ArrayValue arrayValue;

  /// A blob value.
  /// May have at most 1,000,000 bytes.
  /// When `exclude_from_indexes` is false, may have at most 1500 bytes.
  /// In JSON requests, must be base64-encoded.
  core.String blobValue;
  core.List<core.int> get blobValueAsBytes {
    return convert.BASE64.decode(blobValue);
  }

  void set blobValueAsBytes(core.List<core.int> _bytes) {
    blobValue =
        convert.BASE64.encode(_bytes).replaceAll("/", "_").replaceAll("+", "-");
  }

  /// A boolean value.
  core.bool booleanValue;

  /// A double value.
  core.double doubleValue;

  /// An entity value.
  ///
  /// - May have no key.
  /// - May have a key with an incomplete key path.
  /// - May have a reserved/read-only key.
  Entity entityValue;

  /// If the value should be excluded from all indexes including those defined
  /// explicitly.
  core.bool excludeFromIndexes;

  /// A geo point value representing a point on the surface of Earth.
  LatLng geoPointValue;

  /// An integer value.
  core.String integerValue;

  /// A key value.
  Key keyValue;

  /// The `meaning` field should only be populated for backwards compatibility.
  core.int meaning;

  /// A null value.
  /// Possible string values are:
  /// - "NULL_VALUE" : Null value.
  core.String nullValue;

  /// A UTF-8 encoded string value.
  /// When `exclude_from_indexes` is false (it is indexed) , may have at most
  /// 1500 bytes.
  /// Otherwise, may be set to at least 1,000,000 bytes.
  core.String stringValue;

  /// A timestamp value.
  /// When stored in the Datastore, precise only to microseconds;
  /// any additional precision is rounded down.
  core.String timestampValue;

  Value();

  Value.fromJson(core.Map _json) {
    if (_json.containsKey("arrayValue")) {
      arrayValue = new ArrayValue.fromJson(_json["arrayValue"]);
    }
    if (_json.containsKey("blobValue")) {
      blobValue = _json["blobValue"];
    }
    if (_json.containsKey("booleanValue")) {
      booleanValue = _json["booleanValue"];
    }
    if (_json.containsKey("doubleValue")) {
      doubleValue = _json["doubleValue"];
    }
    if (_json.containsKey("entityValue")) {
      entityValue = new Entity.fromJson(_json["entityValue"]);
    }
    if (_json.containsKey("excludeFromIndexes")) {
      excludeFromIndexes = _json["excludeFromIndexes"];
    }
    if (_json.containsKey("geoPointValue")) {
      geoPointValue = new LatLng.fromJson(_json["geoPointValue"]);
    }
    if (_json.containsKey("integerValue")) {
      integerValue = _json["integerValue"];
    }
    if (_json.containsKey("keyValue")) {
      keyValue = new Key.fromJson(_json["keyValue"]);
    }
    if (_json.containsKey("meaning")) {
      meaning = _json["meaning"];
    }
    if (_json.containsKey("nullValue")) {
      nullValue = _json["nullValue"];
    }
    if (_json.containsKey("stringValue")) {
      stringValue = _json["stringValue"];
    }
    if (_json.containsKey("timestampValue")) {
      timestampValue = _json["timestampValue"];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final core.Map<core.String, core.Object> _json =
        new core.Map<core.String, core.Object>();
    if (arrayValue != null) {
      _json["arrayValue"] = (arrayValue).toJson();
    }
    if (blobValue != null) {
      _json["blobValue"] = blobValue;
    }
    if (booleanValue != null) {
      _json["booleanValue"] = booleanValue;
    }
    if (doubleValue != null) {
      _json["doubleValue"] = doubleValue;
    }
    if (entityValue != null) {
      _json["entityValue"] = (entityValue).toJson();
    }
    if (excludeFromIndexes != null) {
      _json["excludeFromIndexes"] = excludeFromIndexes;
    }
    if (geoPointValue != null) {
      _json["geoPointValue"] = (geoPointValue).toJson();
    }
    if (integerValue != null) {
      _json["integerValue"] = integerValue;
    }
    if (keyValue != null) {
      _json["keyValue"] = (keyValue).toJson();
    }
    if (meaning != null) {
      _json["meaning"] = meaning;
    }
    if (nullValue != null) {
      _json["nullValue"] = nullValue;
    }
    if (stringValue != null) {
      _json["stringValue"] = stringValue;
    }
    if (timestampValue != null) {
      _json["timestampValue"] = timestampValue;
    }
    return _json;
  }
}
