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

// ignore_for_file: camel_case_types
// ignore_for_file: comment_references
// ignore_for_file: directives_ordering
// ignore_for_file: file_names
// ignore_for_file: library_names
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: prefer_expression_function_bodies
// ignore_for_file: prefer_final_locals
// ignore_for_file: prefer_interpolation_to_compose_strings
// ignore_for_file: unnecessary_brace_in_string_interps
// ignore_for_file: unnecessary_cast
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: unnecessary_string_interpolations

library googleapis.clouddebugger.v2;

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 userAgent = 'dart-api-client clouddebugger/v2';

/// Examines the call stack and variables of a running application without
/// stopping or slowing it down.
class ClouddebuggerApi {
  /// View and manage your data across Google Cloud Platform services
  static const cloudPlatformScope =
      'https://www.googleapis.com/auth/cloud-platform';

  /// Use Stackdriver Debugger
  static const cloudDebuggerScope =
      'https://www.googleapis.com/auth/cloud_debugger';

  final commons.ApiRequester _requester;

  ControllerResourceApi get controller => ControllerResourceApi(_requester);
  DebuggerResourceApi get debugger => DebuggerResourceApi(_requester);

  ClouddebuggerApi(http.Client client,
      {core.String rootUrl = 'https://clouddebugger.googleapis.com/',
      core.String servicePath = ''})
      : _requester =
            commons.ApiRequester(client, rootUrl, servicePath, userAgent);
}

class ControllerResourceApi {
  final commons.ApiRequester _requester;

  ControllerDebuggeesResourceApi get debuggees =>
      ControllerDebuggeesResourceApi(_requester);

  ControllerResourceApi(commons.ApiRequester client) : _requester = client;
}

class ControllerDebuggeesResourceApi {
  final commons.ApiRequester _requester;

  ControllerDebuggeesBreakpointsResourceApi get breakpoints =>
      ControllerDebuggeesBreakpointsResourceApi(_requester);

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

  /// Registers the debuggee with the controller service. All agents attached to
  /// the same application must call this method with exactly the same request
  /// content to get back the same stable `debuggee_id`. Agents should call this
  /// method again whenever `google.rpc.Code.NOT_FOUND` is returned from any
  /// controller method. This protocol allows the controller service to disable
  /// debuggees, recover from data loss, or change the `debuggee_id` format.
  /// Agents must handle `debuggee_id` value changing upon re-registration.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [RegisterDebuggeeResponse].
  ///
  /// 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<RegisterDebuggeeResponse> register(
    RegisterDebuggeeRequest request, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/controller/debuggees/register';

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

class ControllerDebuggeesBreakpointsResourceApi {
  final commons.ApiRequester _requester;

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

  /// Returns the list of all active breakpoints for the debuggee. The
  /// breakpoint specification (`location`, `condition`, and `expressions`
  /// fields) is semantically immutable, although the field values may change.
  /// For example, an agent may update the location line number to reflect the
  /// actual line where the breakpoint was set, but this doesn't change the
  /// breakpoint semantics. This means that an agent does not need to check if a
  /// breakpoint has changed when it encounters the same breakpoint on a
  /// successive call. Moreover, an agent should remember the breakpoints that
  /// are completed until the controller removes them from the active list to
  /// avoid setting those breakpoints again.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. Identifies the debuggee.
  ///
  /// [agentId] - Identifies the agent. This is the ID returned in the
  /// RegisterDebuggee response.
  ///
  /// [successOnTimeout] - If set to `true` (recommended), returns
  /// `google.rpc.Code.OK` status and sets the `wait_expired` response field to
  /// `true` when the server-selected timeout has expired. If set to `false`
  /// (deprecated), returns `google.rpc.Code.ABORTED` status when the
  /// server-selected timeout has expired.
  ///
  /// [waitToken] - A token that, if specified, blocks the method call until the
  /// list of active breakpoints has changed, or a server-selected timeout has
  /// expired. The value should be set from the `next_wait_token` field in the
  /// last response. The initial value should be set to `"init"`.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [ListActiveBreakpointsResponse].
  ///
  /// 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<ListActiveBreakpointsResponse> list(
    core.String debuggeeId, {
    core.String agentId,
    core.bool successOnTimeout,
    core.String waitToken,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (agentId != null) {
      _queryParams['agentId'] = [agentId];
    }
    if (successOnTimeout != null) {
      _queryParams['successOnTimeout'] = ['${successOnTimeout}'];
    }
    if (waitToken != null) {
      _queryParams['waitToken'] = [waitToken];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/controller/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints';

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

  /// Updates the breakpoint state or mutable fields. The entire Breakpoint
  /// message must be sent back to the controller service. Updates to active
  /// breakpoint fields are only allowed if the new value does not change the
  /// breakpoint specification. Updates to the `location`, `condition` and
  /// `expressions` fields should not alter the breakpoint semantics. These may
  /// only make changes such as canonicalizing a value or snapping the location
  /// to the correct line of code.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. Identifies the debuggee being debugged.
  ///
  /// [id] - Breakpoint identifier, unique in the scope of the debuggee.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [UpdateActiveBreakpointResponse].
  ///
  /// 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<UpdateActiveBreakpointResponse> update(
    UpdateActiveBreakpointRequest request,
    core.String debuggeeId,
    core.String id, {
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (id == null) {
      throw core.ArgumentError('Parameter id is required.');
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/controller/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints/' +
        commons.Escaper.ecapeVariable('$id');

    final _response = _requester.request(
      _url,
      'PUT',
      body: _body,
      queryParams: _queryParams,
      uploadOptions: _uploadOptions,
      uploadMedia: _uploadMedia,
      downloadOptions: _downloadOptions,
    );
    return _response
        .then((data) => UpdateActiveBreakpointResponse.fromJson(data));
  }
}

class DebuggerResourceApi {
  final commons.ApiRequester _requester;

  DebuggerDebuggeesResourceApi get debuggees =>
      DebuggerDebuggeesResourceApi(_requester);

  DebuggerResourceApi(commons.ApiRequester client) : _requester = client;
}

class DebuggerDebuggeesResourceApi {
  final commons.ApiRequester _requester;

  DebuggerDebuggeesBreakpointsResourceApi get breakpoints =>
      DebuggerDebuggeesBreakpointsResourceApi(_requester);

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

  /// Lists all the debuggees that the user has access to.
  ///
  /// Request parameters:
  ///
  /// [clientVersion] - Required. The client version making the call. Schema:
  /// `domain/type/version` (e.g., `google.com/intellij/v1`).
  ///
  /// [includeInactive] - When set to `true`, the result includes all debuggees.
  /// Otherwise, the result includes only debuggees that are active.
  ///
  /// [project] - Required. Project number of a Google Cloud project whose
  /// debuggees to list.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [ListDebuggeesResponse].
  ///
  /// 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<ListDebuggeesResponse> list({
    core.String clientVersion,
    core.bool includeInactive,
    core.String project,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (clientVersion != null) {
      _queryParams['clientVersion'] = [clientVersion];
    }
    if (includeInactive != null) {
      _queryParams['includeInactive'] = ['${includeInactive}'];
    }
    if (project != null) {
      _queryParams['project'] = [project];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/debugger/debuggees';

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

class DebuggerDebuggeesBreakpointsResourceApi {
  final commons.ApiRequester _requester;

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

  /// Deletes the breakpoint from the debuggee.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. ID of the debuggee whose breakpoint to delete.
  ///
  /// [breakpointId] - Required. ID of the breakpoint to delete.
  ///
  /// [clientVersion] - Required. The client version making the call. Schema:
  /// `domain/type/version` (e.g., `google.com/intellij/v1`).
  ///
  /// [$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 debuggeeId,
    core.String breakpointId, {
    core.String clientVersion,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (breakpointId == null) {
      throw core.ArgumentError('Parameter breakpointId is required.');
    }
    if (clientVersion != null) {
      _queryParams['clientVersion'] = [clientVersion];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/debugger/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints/' +
        commons.Escaper.ecapeVariable('$breakpointId');

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

  /// Gets breakpoint information.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. ID of the debuggee whose breakpoint to get.
  ///
  /// [breakpointId] - Required. ID of the breakpoint to get.
  ///
  /// [clientVersion] - Required. The client version making the call. Schema:
  /// `domain/type/version` (e.g., `google.com/intellij/v1`).
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [GetBreakpointResponse].
  ///
  /// 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<GetBreakpointResponse> get(
    core.String debuggeeId,
    core.String breakpointId, {
    core.String clientVersion,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (breakpointId == null) {
      throw core.ArgumentError('Parameter breakpointId is required.');
    }
    if (clientVersion != null) {
      _queryParams['clientVersion'] = [clientVersion];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/debugger/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints/' +
        commons.Escaper.ecapeVariable('$breakpointId');

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

  /// Lists all breakpoints for the debuggee.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. ID of the debuggee whose breakpoints to list.
  ///
  /// [action_value] - Only breakpoints with the specified action will pass the
  /// filter.
  /// Possible string values are:
  /// - "CAPTURE" : Capture stack frame and variables and update the breakpoint.
  /// The data is only captured once. After that the breakpoint is set in a
  /// final state.
  /// - "LOG" : Log each breakpoint hit. The breakpoint remains active until
  /// deleted or expired.
  ///
  /// [clientVersion] - Required. The client version making the call. Schema:
  /// `domain/type/version` (e.g., `google.com/intellij/v1`).
  ///
  /// [includeAllUsers] - When set to `true`, the response includes the list of
  /// breakpoints set by any user. Otherwise, it includes only breakpoints set
  /// by the caller.
  ///
  /// [includeInactive] - When set to `true`, the response includes active and
  /// inactive breakpoints. Otherwise, it includes only active breakpoints.
  ///
  /// [stripResults] - This field is deprecated. The following fields are always
  /// stripped out of the result: `stack_frames`, `evaluated_expressions` and
  /// `variable_table`.
  ///
  /// [waitToken] - A wait token that, if specified, blocks the call until the
  /// breakpoints list has changed, or a server selected timeout has expired.
  /// The value should be set from the last response. The error code
  /// `google.rpc.Code.ABORTED` (RPC) is returned on wait timeout, which should
  /// be called again with the same `wait_token`.
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [ListBreakpointsResponse].
  ///
  /// 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<ListBreakpointsResponse> list(
    core.String debuggeeId, {
    core.String action_value,
    core.String clientVersion,
    core.bool includeAllUsers,
    core.bool includeInactive,
    core.bool stripResults,
    core.String waitToken,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (action_value != null) {
      _queryParams['action.value'] = [action_value];
    }
    if (clientVersion != null) {
      _queryParams['clientVersion'] = [clientVersion];
    }
    if (includeAllUsers != null) {
      _queryParams['includeAllUsers'] = ['${includeAllUsers}'];
    }
    if (includeInactive != null) {
      _queryParams['includeInactive'] = ['${includeInactive}'];
    }
    if (stripResults != null) {
      _queryParams['stripResults'] = ['${stripResults}'];
    }
    if (waitToken != null) {
      _queryParams['waitToken'] = [waitToken];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/debugger/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints';

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

  /// Sets the breakpoint to the debuggee.
  ///
  /// [request] - The metadata request object.
  ///
  /// Request parameters:
  ///
  /// [debuggeeId] - Required. ID of the debuggee where the breakpoint is to be
  /// set.
  ///
  /// [canaryOption] - The canary option set by the user upon setting
  /// breakpoint.
  /// Possible string values are:
  /// - "CANARY_OPTION_UNSPECIFIED" : Depends on the canary_mode of the
  /// debuggee.
  /// - "CANARY_OPTION_TRY_ENABLE" : Enable the canary for this breakpoint if
  /// the canary_mode of the debuggee is not CANARY_MODE_ALWAYS_ENABLED or
  /// CANARY_MODE_ALWAYS_DISABLED.
  /// - "CANARY_OPTION_TRY_DISABLE" : Disable the canary for this breakpoint if
  /// the canary_mode of the debuggee is not CANARY_MODE_ALWAYS_ENABLED or
  /// CANARY_MODE_ALWAYS_DISABLED.
  ///
  /// [clientVersion] - Required. The client version making the call. Schema:
  /// `domain/type/version` (e.g., `google.com/intellij/v1`).
  ///
  /// [$fields] - Selector specifying which fields to include in a partial
  /// response.
  ///
  /// Completes with a [SetBreakpointResponse].
  ///
  /// 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<SetBreakpointResponse> set(
    Breakpoint request,
    core.String debuggeeId, {
    core.String canaryOption,
    core.String clientVersion,
    core.String $fields,
  }) {
    core.String _url;
    final _queryParams = <core.String, core.List<core.String>>{};
    commons.Media _uploadMedia;
    commons.UploadOptions _uploadOptions;
    var _downloadOptions = commons.DownloadOptions.Metadata;
    core.String _body;

    if (request != null) {
      _body = convert.json.encode(request.toJson());
    }
    if (debuggeeId == null) {
      throw core.ArgumentError('Parameter debuggeeId is required.');
    }
    if (canaryOption != null) {
      _queryParams['canaryOption'] = [canaryOption];
    }
    if (clientVersion != null) {
      _queryParams['clientVersion'] = [clientVersion];
    }
    if ($fields != null) {
      _queryParams['fields'] = [$fields];
    }

    _url = 'v2/debugger/debuggees/' +
        commons.Escaper.ecapeVariable('$debuggeeId') +
        '/breakpoints/set';

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

/// An alias to a repo revision.
class AliasContext {
  /// The alias kind.
  /// Possible string values are:
  /// - "ANY" : Do not use.
  /// - "FIXED" : Git tag
  /// - "MOVABLE" : Git branch
  /// - "OTHER" : OTHER is used to specify non-standard aliases, those not of
  /// the kinds above. For example, if a Git repo has a ref named
  /// "refs/foo/bar", it is considered to be of kind OTHER.
  core.String kind;

  /// The alias name.
  core.String name;

  AliasContext();

  AliasContext.fromJson(core.Map _json) {
    if (_json.containsKey('kind')) {
      kind = _json['kind'];
    }
    if (_json.containsKey('name')) {
      name = _json['name'];
    }
  }

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

/// ------------------------------------------------------------------------------
/// ## Breakpoint (the resource) Represents the breakpoint specification, status
/// and results.
class Breakpoint {
  /// Action that the agent should perform when the code at the breakpoint
  /// location is hit.
  /// Possible string values are:
  /// - "CAPTURE" : Capture stack frame and variables and update the breakpoint.
  /// The data is only captured once. After that the breakpoint is set in a
  /// final state.
  /// - "LOG" : Log each breakpoint hit. The breakpoint remains active until
  /// deleted or expired.
  core.String action;

  /// The deadline for the breakpoint to stay in CANARY_ACTIVE state. The value
  /// is meaningless when the breakpoint is not in CANARY_ACTIVE state.
  core.String canaryExpireTime;

  /// Condition that triggers the breakpoint. The condition is a compound
  /// boolean expression composed using expressions in a programming language at
  /// the source location.
  core.String condition;

  /// Time this breakpoint was created by the server in seconds resolution.
  core.String createTime;

  /// Values of evaluated expressions at breakpoint time. The evaluated
  /// expressions appear in exactly the same order they are listed in the
  /// `expressions` field. The `name` field holds the original expression text,
  /// the `value` or `members` field holds the result of the evaluated
  /// expression. If the expression cannot be evaluated, the `status` inside the
  /// `Variable` will indicate an error and contain the error text.
  core.List<Variable> evaluatedExpressions;

  /// List of read-only expressions to evaluate at the breakpoint location. The
  /// expressions are composed using expressions in the programming language at
  /// the source location. If the breakpoint action is `LOG`, the evaluated
  /// expressions are included in log statements.
  core.List<core.String> expressions;

  /// Time this breakpoint was finalized as seen by the server in seconds
  /// resolution.
  core.String finalTime;

  /// Breakpoint identifier, unique in the scope of the debuggee.
  core.String id;

  /// When true, indicates that this is a final result and the breakpoint state
  /// will not change from here on.
  core.bool isFinalState;

  /// A set of custom breakpoint properties, populated by the agent, to be
  /// displayed to the user.
  core.Map<core.String, core.String> labels;

  /// Breakpoint source location.
  SourceLocation location;

  /// Indicates the severity of the log. Only relevant when action is `LOG`.
  /// Possible string values are:
  /// - "INFO" : Information log message.
  /// - "WARNING" : Warning log message.
  /// - "ERROR" : Error log message.
  core.String logLevel;

  /// Only relevant when action is `LOG`. Defines the message to log when the
  /// breakpoint hits. The message may include parameter placeholders `$0`,
  /// `$1`, etc. These placeholders are replaced with the evaluated value of the
  /// appropriate expression. Expressions not referenced in `log_message_format`
  /// are not logged. Example: `Message received, id = $0, count = $1` with
  /// `expressions` = `[ message.id, message.count ]`.
  core.String logMessageFormat;

  /// The stack at breakpoint time, where stack_frames[0] represents the most
  /// recently entered function.
  core.List<StackFrame> stackFrames;

  /// The current state of the breakpoint.
  /// Possible string values are:
  /// - "STATE_UNSPECIFIED" : Breakpoint state UNSPECIFIED.
  /// - "STATE_CANARY_PENDING_AGENTS" : Enabling canary but no agents are
  /// available.
  /// - "STATE_CANARY_ACTIVE" : Enabling canary and successfully assigning
  /// canary agents.
  /// - "STATE_ROLLING_TO_ALL" : Breakpoint rolling out to all agents.
  /// - "STATE_IS_FINAL" : Breakpoint is hit/complete/failed.
  core.String state;

  /// Breakpoint status. The status includes an error flag and a human readable
  /// message. This field is usually unset. The message can be either
  /// informational or an error message. Regardless, clients should always
  /// display the text message back to the user. Error status indicates complete
  /// failure of the breakpoint. Example (non-final state): `Still loading
  /// symbols...` Examples (final state): * `Invalid line number` referring to
  /// location * `Field f not found in class C` referring to condition
  StatusMessage status;

  /// E-mail address of the user that created this breakpoint
  core.String userEmail;

  /// The `variable_table` exists to aid with computation, memory and network
  /// traffic optimization. It enables storing a variable once and reference it
  /// from multiple variables, including variables stored in the
  /// `variable_table` itself. For example, the same `this` object, which may
  /// appear at many levels of the stack, can have all of its data stored once
  /// in this table. The stack frame variables then would hold only a reference
  /// to it. The variable `var_table_index` field is an index into this repeated
  /// field. The stored objects are nameless and get their name from the
  /// referencing variable. The effective variable is a merge of the referencing
  /// variable and the referenced variable.
  core.List<Variable> variableTable;

  Breakpoint();

  Breakpoint.fromJson(core.Map _json) {
    if (_json.containsKey('action')) {
      action = _json['action'];
    }
    if (_json.containsKey('canaryExpireTime')) {
      canaryExpireTime = _json['canaryExpireTime'];
    }
    if (_json.containsKey('condition')) {
      condition = _json['condition'];
    }
    if (_json.containsKey('createTime')) {
      createTime = _json['createTime'];
    }
    if (_json.containsKey('evaluatedExpressions')) {
      evaluatedExpressions = (_json['evaluatedExpressions'] as core.List)
          .map<Variable>((value) => Variable.fromJson(value))
          .toList();
    }
    if (_json.containsKey('expressions')) {
      expressions = (_json['expressions'] as core.List).cast<core.String>();
    }
    if (_json.containsKey('finalTime')) {
      finalTime = _json['finalTime'];
    }
    if (_json.containsKey('id')) {
      id = _json['id'];
    }
    if (_json.containsKey('isFinalState')) {
      isFinalState = _json['isFinalState'];
    }
    if (_json.containsKey('labels')) {
      labels = (_json['labels'] as core.Map).cast<core.String, core.String>();
    }
    if (_json.containsKey('location')) {
      location = SourceLocation.fromJson(_json['location']);
    }
    if (_json.containsKey('logLevel')) {
      logLevel = _json['logLevel'];
    }
    if (_json.containsKey('logMessageFormat')) {
      logMessageFormat = _json['logMessageFormat'];
    }
    if (_json.containsKey('stackFrames')) {
      stackFrames = (_json['stackFrames'] as core.List)
          .map<StackFrame>((value) => StackFrame.fromJson(value))
          .toList();
    }
    if (_json.containsKey('state')) {
      state = _json['state'];
    }
    if (_json.containsKey('status')) {
      status = StatusMessage.fromJson(_json['status']);
    }
    if (_json.containsKey('userEmail')) {
      userEmail = _json['userEmail'];
    }
    if (_json.containsKey('variableTable')) {
      variableTable = (_json['variableTable'] as core.List)
          .map<Variable>((value) => Variable.fromJson(value))
          .toList();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (action != null) {
      _json['action'] = action;
    }
    if (canaryExpireTime != null) {
      _json['canaryExpireTime'] = canaryExpireTime;
    }
    if (condition != null) {
      _json['condition'] = condition;
    }
    if (createTime != null) {
      _json['createTime'] = createTime;
    }
    if (evaluatedExpressions != null) {
      _json['evaluatedExpressions'] =
          evaluatedExpressions.map((value) => value.toJson()).toList();
    }
    if (expressions != null) {
      _json['expressions'] = expressions;
    }
    if (finalTime != null) {
      _json['finalTime'] = finalTime;
    }
    if (id != null) {
      _json['id'] = id;
    }
    if (isFinalState != null) {
      _json['isFinalState'] = isFinalState;
    }
    if (labels != null) {
      _json['labels'] = labels;
    }
    if (location != null) {
      _json['location'] = location.toJson();
    }
    if (logLevel != null) {
      _json['logLevel'] = logLevel;
    }
    if (logMessageFormat != null) {
      _json['logMessageFormat'] = logMessageFormat;
    }
    if (stackFrames != null) {
      _json['stackFrames'] =
          stackFrames.map((value) => value.toJson()).toList();
    }
    if (state != null) {
      _json['state'] = state;
    }
    if (status != null) {
      _json['status'] = status.toJson();
    }
    if (userEmail != null) {
      _json['userEmail'] = userEmail;
    }
    if (variableTable != null) {
      _json['variableTable'] =
          variableTable.map((value) => value.toJson()).toList();
    }
    return _json;
  }
}

/// A CloudRepoSourceContext denotes a particular revision in a cloud repo (a
/// repo hosted by the Google Cloud Platform).
class CloudRepoSourceContext {
  /// An alias, which may be a branch or tag.
  AliasContext aliasContext;

  /// The name of an alias (branch, tag, etc.).
  core.String aliasName;

  /// The ID of the repo.
  RepoId repoId;

  /// A revision ID.
  core.String revisionId;

  CloudRepoSourceContext();

  CloudRepoSourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('aliasContext')) {
      aliasContext = AliasContext.fromJson(_json['aliasContext']);
    }
    if (_json.containsKey('aliasName')) {
      aliasName = _json['aliasName'];
    }
    if (_json.containsKey('repoId')) {
      repoId = RepoId.fromJson(_json['repoId']);
    }
    if (_json.containsKey('revisionId')) {
      revisionId = _json['revisionId'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (aliasContext != null) {
      _json['aliasContext'] = aliasContext.toJson();
    }
    if (aliasName != null) {
      _json['aliasName'] = aliasName;
    }
    if (repoId != null) {
      _json['repoId'] = repoId.toJson();
    }
    if (revisionId != null) {
      _json['revisionId'] = revisionId;
    }
    return _json;
  }
}

/// A CloudWorkspaceId is a unique identifier for a cloud workspace. A cloud
/// workspace is a place associated with a repo where modified files can be
/// stored before they are committed.
class CloudWorkspaceId {
  /// The unique name of the workspace within the repo. This is the name chosen
  /// by the client in the Source API's CreateWorkspace method.
  core.String name;

  /// The ID of the repo containing the workspace.
  RepoId repoId;

  CloudWorkspaceId();

  CloudWorkspaceId.fromJson(core.Map _json) {
    if (_json.containsKey('name')) {
      name = _json['name'];
    }
    if (_json.containsKey('repoId')) {
      repoId = RepoId.fromJson(_json['repoId']);
    }
  }

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

/// A CloudWorkspaceSourceContext denotes a workspace at a particular snapshot.
class CloudWorkspaceSourceContext {
  /// The ID of the snapshot. An empty snapshot_id refers to the most recent
  /// snapshot.
  core.String snapshotId;

  /// The ID of the workspace.
  CloudWorkspaceId workspaceId;

  CloudWorkspaceSourceContext();

  CloudWorkspaceSourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('snapshotId')) {
      snapshotId = _json['snapshotId'];
    }
    if (_json.containsKey('workspaceId')) {
      workspaceId = CloudWorkspaceId.fromJson(_json['workspaceId']);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (snapshotId != null) {
      _json['snapshotId'] = snapshotId;
    }
    if (workspaceId != null) {
      _json['workspaceId'] = workspaceId.toJson();
    }
    return _json;
  }
}

/// Represents the debugged application. The application may include one or more
/// replicated processes executing the same code. Each of these processes is
/// attached with a debugger agent, carrying out the debugging commands. Agents
/// attached to the same debuggee identify themselves as such by using exactly
/// the same Debuggee message value when registering.
class Debuggee {
  /// Version ID of the agent. Schema: `domain/language-platform/vmajor.minor`
  /// (for example `google.com/java-gcp/v1.1`).
  core.String agentVersion;

  /// Used when setting breakpoint canary for this debuggee.
  /// Possible string values are:
  /// - "CANARY_MODE_UNSPECIFIED" : CANARY_MODE_UNSPECIFIED is equivalent to
  /// CANARY_MODE_ALWAYS_DISABLED so that if the debuggee is not configured to
  /// use the canary feature, the feature will be disabled.
  /// - "CANARY_MODE_ALWAYS_ENABLED" : Always enable breakpoint canary
  /// regardless of the value of breakpoint's canary option.
  /// - "CANARY_MODE_ALWAYS_DISABLED" : Always disable breakpoint canary
  /// regardless of the value of breakpoint's canary option.
  /// - "CANARY_MODE_DEFAULT_ENABLED" : Depends on the breakpoint's canary
  /// option. Enable canary by default if the breakpoint's canary option is not
  /// specified.
  /// - "CANARY_MODE_DEFAULT_DISABLED" : Depends on the breakpoint's canary
  /// option. Disable canary by default if the breakpoint's canary option is not
  /// specified.
  core.String canaryMode;

  /// Human readable description of the debuggee. Including a human-readable
  /// project name, environment name and version information is recommended.
  core.String description;

  /// References to the locations and revisions of the source code used in the
  /// deployed application.
  core.List<ExtendedSourceContext> extSourceContexts;

  /// Unique identifier for the debuggee generated by the controller service.
  core.String id;

  /// If set to `true`, indicates that the agent should disable itself and
  /// detach from the debuggee.
  core.bool isDisabled;

  /// If set to `true`, indicates that Controller service does not detect any
  /// activity from the debuggee agents and the application is possibly stopped.
  core.bool isInactive;

  /// A set of custom debuggee properties, populated by the agent, to be
  /// displayed to the user.
  core.Map<core.String, core.String> labels;

  /// Project the debuggee is associated with. Use project number or id when
  /// registering a Google Cloud Platform project.
  core.String project;

  /// References to the locations and revisions of the source code used in the
  /// deployed application.
  core.List<SourceContext> sourceContexts;

  /// Human readable message to be displayed to the user about this debuggee.
  /// Absence of this field indicates no status. The message can be either
  /// informational or an error status.
  StatusMessage status;

  /// Uniquifier to further distinguish the application. It is possible that
  /// different applications might have identical values in the debuggee
  /// message, thus, incorrectly identified as a single application by the
  /// Controller service. This field adds salt to further distinguish the
  /// application. Agents should consider seeding this field with value that
  /// identifies the code, binary, configuration and environment.
  core.String uniquifier;

  Debuggee();

  Debuggee.fromJson(core.Map _json) {
    if (_json.containsKey('agentVersion')) {
      agentVersion = _json['agentVersion'];
    }
    if (_json.containsKey('canaryMode')) {
      canaryMode = _json['canaryMode'];
    }
    if (_json.containsKey('description')) {
      description = _json['description'];
    }
    if (_json.containsKey('extSourceContexts')) {
      extSourceContexts = (_json['extSourceContexts'] as core.List)
          .map<ExtendedSourceContext>(
              (value) => ExtendedSourceContext.fromJson(value))
          .toList();
    }
    if (_json.containsKey('id')) {
      id = _json['id'];
    }
    if (_json.containsKey('isDisabled')) {
      isDisabled = _json['isDisabled'];
    }
    if (_json.containsKey('isInactive')) {
      isInactive = _json['isInactive'];
    }
    if (_json.containsKey('labels')) {
      labels = (_json['labels'] as core.Map).cast<core.String, core.String>();
    }
    if (_json.containsKey('project')) {
      project = _json['project'];
    }
    if (_json.containsKey('sourceContexts')) {
      sourceContexts = (_json['sourceContexts'] as core.List)
          .map<SourceContext>((value) => SourceContext.fromJson(value))
          .toList();
    }
    if (_json.containsKey('status')) {
      status = StatusMessage.fromJson(_json['status']);
    }
    if (_json.containsKey('uniquifier')) {
      uniquifier = _json['uniquifier'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (agentVersion != null) {
      _json['agentVersion'] = agentVersion;
    }
    if (canaryMode != null) {
      _json['canaryMode'] = canaryMode;
    }
    if (description != null) {
      _json['description'] = description;
    }
    if (extSourceContexts != null) {
      _json['extSourceContexts'] =
          extSourceContexts.map((value) => value.toJson()).toList();
    }
    if (id != null) {
      _json['id'] = id;
    }
    if (isDisabled != null) {
      _json['isDisabled'] = isDisabled;
    }
    if (isInactive != null) {
      _json['isInactive'] = isInactive;
    }
    if (labels != null) {
      _json['labels'] = labels;
    }
    if (project != null) {
      _json['project'] = project;
    }
    if (sourceContexts != null) {
      _json['sourceContexts'] =
          sourceContexts.map((value) => value.toJson()).toList();
    }
    if (status != null) {
      _json['status'] = status.toJson();
    }
    if (uniquifier != null) {
      _json['uniquifier'] = uniquifier;
    }
    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(
      // ignore: avoid_unused_constructor_parameters
      core.Map _json);

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

/// An ExtendedSourceContext is a SourceContext combined with additional details
/// describing the context.
class ExtendedSourceContext {
  /// Any source context.
  SourceContext context;

  /// Labels with user defined metadata.
  core.Map<core.String, core.String> labels;

  ExtendedSourceContext();

  ExtendedSourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('context')) {
      context = SourceContext.fromJson(_json['context']);
    }
    if (_json.containsKey('labels')) {
      labels = (_json['labels'] as core.Map).cast<core.String, core.String>();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (context != null) {
      _json['context'] = context.toJson();
    }
    if (labels != null) {
      _json['labels'] = labels;
    }
    return _json;
  }
}

/// Represents a message with parameters.
class FormatMessage {
  /// Format template for the message. The `format` uses placeholders `$0`,
  /// `$1`, etc. to reference parameters. `$$` can be used to denote the `$`
  /// character. Examples: * `Failed to load '$0' which helps debug $1 the first
  /// time it is loaded. Again, $0 is very important.` * `Please pay $$10 to use
  /// $0 instead of $1.`
  core.String format;

  /// Optional parameters to be embedded into the message.
  core.List<core.String> parameters;

  FormatMessage();

  FormatMessage.fromJson(core.Map _json) {
    if (_json.containsKey('format')) {
      format = _json['format'];
    }
    if (_json.containsKey('parameters')) {
      parameters = (_json['parameters'] as core.List).cast<core.String>();
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (format != null) {
      _json['format'] = format;
    }
    if (parameters != null) {
      _json['parameters'] = parameters;
    }
    return _json;
  }
}

/// A SourceContext referring to a Gerrit project.
class GerritSourceContext {
  /// An alias, which may be a branch or tag.
  AliasContext aliasContext;

  /// The name of an alias (branch, tag, etc.).
  core.String aliasName;

  /// The full project name within the host. Projects may be nested, so
  /// "project/subproject" is a valid project name. The "repo name" is
  /// hostURI/project.
  core.String gerritProject;

  /// The URI of a running Gerrit instance.
  core.String hostUri;

  /// A revision (commit) ID.
  core.String revisionId;

  GerritSourceContext();

  GerritSourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('aliasContext')) {
      aliasContext = AliasContext.fromJson(_json['aliasContext']);
    }
    if (_json.containsKey('aliasName')) {
      aliasName = _json['aliasName'];
    }
    if (_json.containsKey('gerritProject')) {
      gerritProject = _json['gerritProject'];
    }
    if (_json.containsKey('hostUri')) {
      hostUri = _json['hostUri'];
    }
    if (_json.containsKey('revisionId')) {
      revisionId = _json['revisionId'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (aliasContext != null) {
      _json['aliasContext'] = aliasContext.toJson();
    }
    if (aliasName != null) {
      _json['aliasName'] = aliasName;
    }
    if (gerritProject != null) {
      _json['gerritProject'] = gerritProject;
    }
    if (hostUri != null) {
      _json['hostUri'] = hostUri;
    }
    if (revisionId != null) {
      _json['revisionId'] = revisionId;
    }
    return _json;
  }
}

/// Response for getting breakpoint information.
class GetBreakpointResponse {
  /// Complete breakpoint state. The fields `id` and `location` are guaranteed
  /// to be set.
  Breakpoint breakpoint;

  GetBreakpointResponse();

  GetBreakpointResponse.fromJson(core.Map _json) {
    if (_json.containsKey('breakpoint')) {
      breakpoint = Breakpoint.fromJson(_json['breakpoint']);
    }
  }

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

/// A GitSourceContext denotes a particular revision in a third party Git
/// repository (e.g. GitHub).
class GitSourceContext {
  /// Git commit hash. required.
  core.String revisionId;

  /// Git repository URL.
  core.String url;

  GitSourceContext();

  GitSourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('revisionId')) {
      revisionId = _json['revisionId'];
    }
    if (_json.containsKey('url')) {
      url = _json['url'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (revisionId != null) {
      _json['revisionId'] = revisionId;
    }
    if (url != null) {
      _json['url'] = url;
    }
    return _json;
  }
}

/// Response for listing active breakpoints.
class ListActiveBreakpointsResponse {
  /// List of all active breakpoints. The fields `id` and `location` are
  /// guaranteed to be set on each breakpoint.
  core.List<Breakpoint> breakpoints;

  /// A token that can be used in the next method call to block until the list
  /// of breakpoints changes.
  core.String nextWaitToken;

  /// If set to `true`, indicates that there is no change to the list of active
  /// breakpoints and the server-selected timeout has expired. The `breakpoints`
  /// field would be empty and should be ignored.
  core.bool waitExpired;

  ListActiveBreakpointsResponse();

  ListActiveBreakpointsResponse.fromJson(core.Map _json) {
    if (_json.containsKey('breakpoints')) {
      breakpoints = (_json['breakpoints'] as core.List)
          .map<Breakpoint>((value) => Breakpoint.fromJson(value))
          .toList();
    }
    if (_json.containsKey('nextWaitToken')) {
      nextWaitToken = _json['nextWaitToken'];
    }
    if (_json.containsKey('waitExpired')) {
      waitExpired = _json['waitExpired'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (breakpoints != null) {
      _json['breakpoints'] =
          breakpoints.map((value) => value.toJson()).toList();
    }
    if (nextWaitToken != null) {
      _json['nextWaitToken'] = nextWaitToken;
    }
    if (waitExpired != null) {
      _json['waitExpired'] = waitExpired;
    }
    return _json;
  }
}

/// Response for listing breakpoints.
class ListBreakpointsResponse {
  /// List of breakpoints matching the request. The fields `id` and `location`
  /// are guaranteed to be set on each breakpoint. The fields: `stack_frames`,
  /// `evaluated_expressions` and `variable_table` are cleared on each
  /// breakpoint regardless of its status.
  core.List<Breakpoint> breakpoints;

  /// A wait token that can be used in the next call to `list` (REST) or
  /// `ListBreakpoints` (RPC) to block until the list of breakpoints has
  /// changes.
  core.String nextWaitToken;

  ListBreakpointsResponse();

  ListBreakpointsResponse.fromJson(core.Map _json) {
    if (_json.containsKey('breakpoints')) {
      breakpoints = (_json['breakpoints'] as core.List)
          .map<Breakpoint>((value) => Breakpoint.fromJson(value))
          .toList();
    }
    if (_json.containsKey('nextWaitToken')) {
      nextWaitToken = _json['nextWaitToken'];
    }
  }

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

/// Response for listing debuggees.
class ListDebuggeesResponse {
  /// List of debuggees accessible to the calling user. The fields `debuggee.id`
  /// and `description` are guaranteed to be set. The `description` field is a
  /// human readable field provided by agents and can be displayed to users.
  core.List<Debuggee> debuggees;

  ListDebuggeesResponse();

  ListDebuggeesResponse.fromJson(core.Map _json) {
    if (_json.containsKey('debuggees')) {
      debuggees = (_json['debuggees'] as core.List)
          .map<Debuggee>((value) => Debuggee.fromJson(value))
          .toList();
    }
  }

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

/// Selects a repo using a Google Cloud Platform project ID (e.g.
/// winged-cargo-31) and a repo name within that project.
class ProjectRepoId {
  /// The ID of the project.
  core.String projectId;

  /// The name of the repo. Leave empty for the default repo.
  core.String repoName;

  ProjectRepoId();

  ProjectRepoId.fromJson(core.Map _json) {
    if (_json.containsKey('projectId')) {
      projectId = _json['projectId'];
    }
    if (_json.containsKey('repoName')) {
      repoName = _json['repoName'];
    }
  }

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

/// Request to register a debuggee.
class RegisterDebuggeeRequest {
  /// Required. Debuggee information to register. The fields `project`,
  /// `uniquifier`, `description` and `agent_version` of the debuggee must be
  /// set.
  Debuggee debuggee;

  RegisterDebuggeeRequest();

  RegisterDebuggeeRequest.fromJson(core.Map _json) {
    if (_json.containsKey('debuggee')) {
      debuggee = Debuggee.fromJson(_json['debuggee']);
    }
  }

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

/// Response for registering a debuggee.
class RegisterDebuggeeResponse {
  /// A unique ID generated for the agent. Each RegisterDebuggee request will
  /// generate a new agent ID.
  core.String agentId;

  /// Debuggee resource. The field `id` is guaranteed to be set (in addition to
  /// the echoed fields). If the field `is_disabled` is set to `true`, the agent
  /// should disable itself by removing all breakpoints and detaching from the
  /// application. It should however continue to poll `RegisterDebuggee` until
  /// reenabled.
  Debuggee debuggee;

  RegisterDebuggeeResponse();

  RegisterDebuggeeResponse.fromJson(core.Map _json) {
    if (_json.containsKey('agentId')) {
      agentId = _json['agentId'];
    }
    if (_json.containsKey('debuggee')) {
      debuggee = Debuggee.fromJson(_json['debuggee']);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (agentId != null) {
      _json['agentId'] = agentId;
    }
    if (debuggee != null) {
      _json['debuggee'] = debuggee.toJson();
    }
    return _json;
  }
}

/// A unique identifier for a cloud repo.
class RepoId {
  /// A combination of a project ID and a repo name.
  ProjectRepoId projectRepoId;

  /// A server-assigned, globally unique identifier.
  core.String uid;

  RepoId();

  RepoId.fromJson(core.Map _json) {
    if (_json.containsKey('projectRepoId')) {
      projectRepoId = ProjectRepoId.fromJson(_json['projectRepoId']);
    }
    if (_json.containsKey('uid')) {
      uid = _json['uid'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (projectRepoId != null) {
      _json['projectRepoId'] = projectRepoId.toJson();
    }
    if (uid != null) {
      _json['uid'] = uid;
    }
    return _json;
  }
}

/// Response for setting a breakpoint.
class SetBreakpointResponse {
  /// Breakpoint resource. The field `id` is guaranteed to be set (in addition
  /// to the echoed fields).
  Breakpoint breakpoint;

  SetBreakpointResponse();

  SetBreakpointResponse.fromJson(core.Map _json) {
    if (_json.containsKey('breakpoint')) {
      breakpoint = Breakpoint.fromJson(_json['breakpoint']);
    }
  }

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

/// A SourceContext is a reference to a tree of files. A SourceContext together
/// with a path point to a unique revision of a single file or directory.
class SourceContext {
  /// A SourceContext referring to a revision in a cloud repo.
  CloudRepoSourceContext cloudRepo;

  /// A SourceContext referring to a snapshot in a cloud workspace.
  CloudWorkspaceSourceContext cloudWorkspace;

  /// A SourceContext referring to a Gerrit project.
  GerritSourceContext gerrit;

  /// A SourceContext referring to any third party Git repo (e.g. GitHub).
  GitSourceContext git;

  SourceContext();

  SourceContext.fromJson(core.Map _json) {
    if (_json.containsKey('cloudRepo')) {
      cloudRepo = CloudRepoSourceContext.fromJson(_json['cloudRepo']);
    }
    if (_json.containsKey('cloudWorkspace')) {
      cloudWorkspace =
          CloudWorkspaceSourceContext.fromJson(_json['cloudWorkspace']);
    }
    if (_json.containsKey('gerrit')) {
      gerrit = GerritSourceContext.fromJson(_json['gerrit']);
    }
    if (_json.containsKey('git')) {
      git = GitSourceContext.fromJson(_json['git']);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (cloudRepo != null) {
      _json['cloudRepo'] = cloudRepo.toJson();
    }
    if (cloudWorkspace != null) {
      _json['cloudWorkspace'] = cloudWorkspace.toJson();
    }
    if (gerrit != null) {
      _json['gerrit'] = gerrit.toJson();
    }
    if (git != null) {
      _json['git'] = git.toJson();
    }
    return _json;
  }
}

/// Represents a location in the source code.
class SourceLocation {
  /// Column within a line. The first column in a line as the value `1`. Agents
  /// that do not support setting breakpoints on specific columns ignore this
  /// field.
  core.int column;

  /// Line inside the file. The first line in the file has the value `1`.
  core.int line;

  /// Path to the source file within the source context of the target binary.
  core.String path;

  SourceLocation();

  SourceLocation.fromJson(core.Map _json) {
    if (_json.containsKey('column')) {
      column = _json['column'];
    }
    if (_json.containsKey('line')) {
      line = _json['line'];
    }
    if (_json.containsKey('path')) {
      path = _json['path'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (column != null) {
      _json['column'] = column;
    }
    if (line != null) {
      _json['line'] = line;
    }
    if (path != null) {
      _json['path'] = path;
    }
    return _json;
  }
}

/// Represents a stack frame context.
class StackFrame {
  /// Set of arguments passed to this function. Note that this might not be
  /// populated for all stack frames.
  core.List<Variable> arguments;

  /// Demangled function name at the call site.
  core.String function;

  /// Set of local variables at the stack frame location. Note that this might
  /// not be populated for all stack frames.
  core.List<Variable> locals;

  /// Source location of the call site.
  SourceLocation location;

  StackFrame();

  StackFrame.fromJson(core.Map _json) {
    if (_json.containsKey('arguments')) {
      arguments = (_json['arguments'] as core.List)
          .map<Variable>((value) => Variable.fromJson(value))
          .toList();
    }
    if (_json.containsKey('function')) {
      function = _json['function'];
    }
    if (_json.containsKey('locals')) {
      locals = (_json['locals'] as core.List)
          .map<Variable>((value) => Variable.fromJson(value))
          .toList();
    }
    if (_json.containsKey('location')) {
      location = SourceLocation.fromJson(_json['location']);
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (arguments != null) {
      _json['arguments'] = arguments.map((value) => value.toJson()).toList();
    }
    if (function != null) {
      _json['function'] = function;
    }
    if (locals != null) {
      _json['locals'] = locals.map((value) => value.toJson()).toList();
    }
    if (location != null) {
      _json['location'] = location.toJson();
    }
    return _json;
  }
}

/// Represents a contextual status message. The message can indicate an error or
/// informational status, and refer to specific parts of the containing object.
/// For example, the `Breakpoint.status` field can indicate an error referring
/// to the `BREAKPOINT_SOURCE_LOCATION` with the message `Location not found`.
class StatusMessage {
  /// Status message text.
  FormatMessage description;

  /// Distinguishes errors from informational messages.
  core.bool isError;

  /// Reference to which the message applies.
  /// Possible string values are:
  /// - "UNSPECIFIED" : Status doesn't refer to any particular input.
  /// - "BREAKPOINT_SOURCE_LOCATION" : Status applies to the breakpoint and is
  /// related to its location.
  /// - "BREAKPOINT_CONDITION" : Status applies to the breakpoint and is related
  /// to its condition.
  /// - "BREAKPOINT_EXPRESSION" : Status applies to the breakpoint and is
  /// related to its expressions.
  /// - "BREAKPOINT_AGE" : Status applies to the breakpoint and is related to
  /// its age.
  /// - "BREAKPOINT_CANARY_FAILED" : Status applies to the breakpoint when the
  /// breakpoint failed to exit the canary state.
  /// - "VARIABLE_NAME" : Status applies to the entire variable.
  /// - "VARIABLE_VALUE" : Status applies to variable value (variable name is
  /// valid).
  core.String refersTo;

  StatusMessage();

  StatusMessage.fromJson(core.Map _json) {
    if (_json.containsKey('description')) {
      description = FormatMessage.fromJson(_json['description']);
    }
    if (_json.containsKey('isError')) {
      isError = _json['isError'];
    }
    if (_json.containsKey('refersTo')) {
      refersTo = _json['refersTo'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (description != null) {
      _json['description'] = description.toJson();
    }
    if (isError != null) {
      _json['isError'] = isError;
    }
    if (refersTo != null) {
      _json['refersTo'] = refersTo;
    }
    return _json;
  }
}

/// Request to update an active breakpoint.
class UpdateActiveBreakpointRequest {
  /// Required. Updated breakpoint information. The field `id` must be set. The
  /// agent must echo all Breakpoint specification fields in the update.
  Breakpoint breakpoint;

  UpdateActiveBreakpointRequest();

  UpdateActiveBreakpointRequest.fromJson(core.Map _json) {
    if (_json.containsKey('breakpoint')) {
      breakpoint = Breakpoint.fromJson(_json['breakpoint']);
    }
  }

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

/// Response for updating an active breakpoint. The message is defined to allow
/// future extensions.
class UpdateActiveBreakpointResponse {
  UpdateActiveBreakpointResponse();

  UpdateActiveBreakpointResponse.fromJson(
      // ignore: avoid_unused_constructor_parameters
      core.Map _json);

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

/// Represents a variable or an argument possibly of a compound object type.
/// Note how the following variables are represented: 1) A simple variable: int
/// x = 5 { name: "x", value: "5", type: "int" } // Captured variable 2) A
/// compound object: struct T { int m1; int m2; }; T x = { 3, 7 }; { // Captured
/// variable name: "x", type: "T", members { name: "m1", value: "3", type: "int"
/// }, members { name: "m2", value: "7", type: "int" } } 3) A pointer where the
/// pointee was captured: T x = { 3, 7 }; T* p = &x; { // Captured variable
/// name: "p", type: "T*", value: "0x00500500", members { name: "m1", value:
/// "3", type: "int" }, members { name: "m2", value: "7", type: "int" } } 4) A
/// pointer where the pointee was not captured: T* p = new T; { // Captured
/// variable name: "p", type: "T*", value: "0x00400400" status { is_error: true,
/// description { format: "unavailable" } } } The status should describe the
/// reason for the missing value, such as ``, ``, ``. Note that a null pointer
/// should not have members. 5) An unnamed value: int* p = new int(7); { //
/// Captured variable name: "p", value: "0x00500500", type: "int*", members {
/// value: "7", type: "int" } } 6) An unnamed pointer where the pointee was not
/// captured: int* p = new int(7); int** pp = &p; { // Captured variable name:
/// "pp", value: "0x00500500", type: "int**", members { value: "0x00400400",
/// type: "int*" status { is_error: true, description: { format: "unavailable" }
/// } } } } To optimize computation, memory and network traffic, variables that
/// repeat in the output multiple times can be stored once in a shared variable
/// table and be referenced using the `var_table_index` field. The variables
/// stored in the shared table are nameless and are essentially a partition of
/// the complete variable. To reconstruct the complete variable, merge the
/// referencing variable with the referenced variable. When using the shared
/// variable table, the following variables: T x = { 3, 7 }; T* p = &x; T& r =
/// x; { name: "x", var_table_index: 3, type: "T" } // Captured variables {
/// name: "p", value "0x00500500", type="T*", var_table_index: 3 } { name: "r",
/// type="T&", var_table_index: 3 } { // Shared variable table entry #3: members
/// { name: "m1", value: "3", type: "int" }, members { name: "m2", value: "7",
/// type: "int" } } Note that the pointer address is stored with the referencing
/// variable and not with the referenced variable. This allows the referenced
/// variable to be shared between pointers and references. The type field is
/// optional. The debugger agent may or may not support it.
class Variable {
  /// Members contained or pointed to by the variable.
  core.List<Variable> members;

  /// Name of the variable, if any.
  core.String name;

  /// Status associated with the variable. This field will usually stay unset. A
  /// status of a single variable only applies to that variable or expression.
  /// The rest of breakpoint data still remains valid. Variables might be
  /// reported in error state even when breakpoint is not in final state. The
  /// message may refer to variable name with `refers_to` set to
  /// `VARIABLE_NAME`. Alternatively `refers_to` will be set to
  /// `VARIABLE_VALUE`. In either case variable value and members will be unset.
  /// Example of error message applied to name: `Invalid expression syntax`.
  /// Example of information message applied to value: `Not captured`. Examples
  /// of error message applied to value: * `Malformed string`, * `Field f not
  /// found in class C` * `Null pointer dereference`
  StatusMessage status;

  /// Variable type (e.g. `MyClass`). If the variable is split with
  /// `var_table_index`, `type` goes next to `value`. The interpretation of a
  /// type is agent specific. It is recommended to include the dynamic type
  /// rather than a static type of an object.
  core.String type;

  /// Simple value of the variable.
  core.String value;

  /// Reference to a variable in the shared variable table. More than one
  /// variable can reference the same variable in the table. The
  /// `var_table_index` field is an index into `variable_table` in Breakpoint.
  core.int varTableIndex;

  Variable();

  Variable.fromJson(core.Map _json) {
    if (_json.containsKey('members')) {
      members = (_json['members'] as core.List)
          .map<Variable>((value) => Variable.fromJson(value))
          .toList();
    }
    if (_json.containsKey('name')) {
      name = _json['name'];
    }
    if (_json.containsKey('status')) {
      status = StatusMessage.fromJson(_json['status']);
    }
    if (_json.containsKey('type')) {
      type = _json['type'];
    }
    if (_json.containsKey('value')) {
      value = _json['value'];
    }
    if (_json.containsKey('varTableIndex')) {
      varTableIndex = _json['varTableIndex'];
    }
  }

  core.Map<core.String, core.Object> toJson() {
    final _json = <core.String, core.Object>{};
    if (members != null) {
      _json['members'] = members.map((value) => value.toJson()).toList();
    }
    if (name != null) {
      _json['name'] = name;
    }
    if (status != null) {
      _json['status'] = status.toJson();
    }
    if (type != null) {
      _json['type'] = type;
    }
    if (value != null) {
      _json['value'] = value;
    }
    if (varTableIndex != null) {
      _json['varTableIndex'] = varTableIndex;
    }
    return _json;
  }
}
