// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This code was auto-generated by tool/dap/generate_all.dart; do not hand-edit!

// ignore_for_file: prefer_void_to_null

import 'protocol_common.dart';
import 'protocol_special.dart';

/// Arguments for 'attach' request. Additional attributes are implementation
/// specific.
class AttachRequestArguments extends RequestArguments {
  /// Optional data from the previous, restarted session.
  /// The data is sent as the 'restart' attribute of the 'terminated' event.
  /// The client should leave the data intact.
  final Object? restart;

  static AttachRequestArguments fromJson(Map<String, Object?> obj) =>
      AttachRequestArguments.fromMap(obj);

  AttachRequestArguments({
    this.restart,
  });

  AttachRequestArguments.fromMap(Map<String, Object?> obj)
      : restart = obj['__restart'];

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (restart != null) '__restart': restart,
      };
}

/// Response to 'attach' request. This is just an acknowledgement, so no body
/// field is required.
class AttachResponse extends Response {
  static AttachResponse fromJson(Map<String, Object?> obj) =>
      AttachResponse.fromMap(obj);

  AttachResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  AttachResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Information about a Breakpoint created in setBreakpoints,
/// setFunctionBreakpoints, setInstructionBreakpoints, or setDataBreakpoints.
class Breakpoint {
  /// An optional start column of the actual range covered by the breakpoint.
  final int? column;

  /// An optional end column of the actual range covered by the breakpoint.
  /// If no end line is given, then the end column is assumed to be in the start
  /// line.
  final int? endColumn;

  /// An optional end line of the actual range covered by the breakpoint.
  final int? endLine;

  /// An optional identifier for the breakpoint. It is needed if breakpoint
  /// events are used to update or remove breakpoints.
  final int? id;

  /// An optional memory reference to where the breakpoint is set.
  final String? instructionReference;

  /// The start line of the actual range covered by the breakpoint.
  final int? line;

  /// An optional message about the state of the breakpoint.
  /// This is shown to the user and can be used to explain why a breakpoint
  /// could not be verified.
  final String? message;

  /// An optional offset from the instruction reference.
  /// This can be negative.
  final int? offset;

  /// The source where the breakpoint is located.
  final Source? source;

  /// If true breakpoint could be set (but not necessarily at the desired
  /// location).
  final bool verified;

  static Breakpoint fromJson(Map<String, Object?> obj) =>
      Breakpoint.fromMap(obj);

  Breakpoint({
    this.column,
    this.endColumn,
    this.endLine,
    this.id,
    this.instructionReference,
    this.line,
    this.message,
    this.offset,
    this.source,
    required this.verified,
  });

  Breakpoint.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        id = obj['id'] as int?,
        instructionReference = obj['instructionReference'] as String?,
        line = obj['line'] as int?,
        message = obj['message'] as String?,
        offset = obj['offset'] as int?,
        source = obj['source'] == null
            ? null
            : Source.fromJson(obj['source'] as Map<String, Object?>),
        verified = obj['verified'] as bool;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['id'] is! int?) {
      return false;
    }
    if (obj['instructionReference'] is! String?) {
      return false;
    }
    if (obj['line'] is! int?) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['offset'] is! int?) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    if (obj['verified'] is! bool) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        if (id != null) 'id': id,
        if (instructionReference != null)
          'instructionReference': instructionReference,
        if (line != null) 'line': line,
        if (message != null) 'message': message,
        if (offset != null) 'offset': offset,
        if (source != null) 'source': source,
        'verified': verified,
      };
}

/// Properties of a breakpoint location returned from the 'breakpointLocations'
/// request.
class BreakpointLocation {
  /// Optional start column of breakpoint location.
  final int? column;

  /// Optional end column of breakpoint location if the location covers a range.
  final int? endColumn;

  /// Optional end line of breakpoint location if the location covers a range.
  final int? endLine;

  /// Start line of breakpoint location.
  final int line;

  static BreakpointLocation fromJson(Map<String, Object?> obj) =>
      BreakpointLocation.fromMap(obj);

  BreakpointLocation({
    this.column,
    this.endColumn,
    this.endLine,
    required this.line,
  });

  BreakpointLocation.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        line = obj['line'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'line': line,
      };
}

/// Arguments for 'breakpointLocations' request.
class BreakpointLocationsArguments extends RequestArguments {
  /// Optional start column of range to search possible breakpoint locations in.
  /// If no start column is given, the first column in the start line is
  /// assumed.
  final int? column;

  /// Optional end column of range to search possible breakpoint locations in.
  /// If no end column is given, then it is assumed to be in the last column of
  /// the end line.
  final int? endColumn;

  /// Optional end line of range to search possible breakpoint locations in. If
  /// no end line is given, then the end line is assumed to be the start line.
  final int? endLine;

  /// Start line of range to search possible breakpoint locations in. If only
  /// the line is specified, the request returns all possible locations in that
  /// line.
  final int line;

  /// The source location of the breakpoints; either 'source.path' or
  /// 'source.reference' must be specified.
  final Source source;

  static BreakpointLocationsArguments fromJson(Map<String, Object?> obj) =>
      BreakpointLocationsArguments.fromMap(obj);

  BreakpointLocationsArguments({
    this.column,
    this.endColumn,
    this.endLine,
    required this.line,
    required this.source,
  });

  BreakpointLocationsArguments.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        line = obj['line'] as int,
        source = Source.fromJson(obj['source'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'line': line,
        'source': source,
      };
}

/// Response to 'breakpointLocations' request.
/// Contains possible locations for source breakpoints.
class BreakpointLocationsResponse extends Response {
  static BreakpointLocationsResponse fromJson(Map<String, Object?> obj) =>
      BreakpointLocationsResponse.fromMap(obj);

  BreakpointLocationsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  BreakpointLocationsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'cancel' request.
class CancelArguments extends RequestArguments {
  /// The ID (attribute 'progressId') of the progress to cancel. If missing no
  /// progress is cancelled.
  /// Both a 'requestId' and a 'progressId' can be specified in one request.
  final String? progressId;

  /// The ID (attribute 'seq') of the request to cancel. If missing no request
  /// is cancelled.
  /// Both a 'requestId' and a 'progressId' can be specified in one request.
  final int? requestId;

  static CancelArguments fromJson(Map<String, Object?> obj) =>
      CancelArguments.fromMap(obj);

  CancelArguments({
    this.progressId,
    this.requestId,
  });

  CancelArguments.fromMap(Map<String, Object?> obj)
      : progressId = obj['progressId'] as String?,
        requestId = obj['requestId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['progressId'] is! String?) {
      return false;
    }
    if (obj['requestId'] is! int?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (progressId != null) 'progressId': progressId,
        if (requestId != null) 'requestId': requestId,
      };
}

/// Response to 'cancel' request. This is just an acknowledgement, so no body
/// field is required.
class CancelResponse extends Response {
  static CancelResponse fromJson(Map<String, Object?> obj) =>
      CancelResponse.fromMap(obj);

  CancelResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  CancelResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Information about the capabilities of a debug adapter.
class Capabilities {
  /// The set of additional module information exposed by the debug adapter.
  final List<ColumnDescriptor>? additionalModuleColumns;

  /// The set of characters that should trigger completion in a REPL. If not
  /// specified, the UI should assume the '.' character.
  final List<String>? completionTriggerCharacters;

  /// Available exception filter options for the 'setExceptionBreakpoints'
  /// request.
  final List<ExceptionBreakpointsFilter>? exceptionBreakpointFilters;

  /// The debug adapter supports the 'suspendDebuggee' attribute on the
  /// 'disconnect' request.
  final bool? supportSuspendDebuggee;

  /// The debug adapter supports the 'terminateDebuggee' attribute on the
  /// 'disconnect' request.
  final bool? supportTerminateDebuggee;

  /// Checksum algorithms supported by the debug adapter.
  final List<ChecksumAlgorithm>? supportedChecksumAlgorithms;

  /// The debug adapter supports the 'breakpointLocations' request.
  final bool? supportsBreakpointLocationsRequest;

  /// The debug adapter supports the 'cancel' request.
  final bool? supportsCancelRequest;

  /// The debug adapter supports the 'clipboard' context value in the 'evaluate'
  /// request.
  final bool? supportsClipboardContext;

  /// The debug adapter supports the 'completions' request.
  final bool? supportsCompletionsRequest;

  /// The debug adapter supports conditional breakpoints.
  final bool? supportsConditionalBreakpoints;

  /// The debug adapter supports the 'configurationDone' request.
  final bool? supportsConfigurationDoneRequest;

  /// The debug adapter supports data breakpoints.
  final bool? supportsDataBreakpoints;

  /// The debug adapter supports the delayed loading of parts of the stack,
  /// which requires that both the 'startFrame' and 'levels' arguments and an
  /// optional 'totalFrames' result of the 'StackTrace' request are supported.
  final bool? supportsDelayedStackTraceLoading;

  /// The debug adapter supports the 'disassemble' request.
  final bool? supportsDisassembleRequest;

  /// The debug adapter supports a (side effect free) evaluate request for data
  /// hovers.
  final bool? supportsEvaluateForHovers;

  /// The debug adapter supports 'filterOptions' as an argument on the
  /// 'setExceptionBreakpoints' request.
  final bool? supportsExceptionFilterOptions;

  /// The debug adapter supports the 'exceptionInfo' request.
  final bool? supportsExceptionInfoRequest;

  /// The debug adapter supports 'exceptionOptions' on the
  /// setExceptionBreakpoints request.
  final bool? supportsExceptionOptions;

  /// The debug adapter supports function breakpoints.
  final bool? supportsFunctionBreakpoints;

  /// The debug adapter supports the 'gotoTargets' request.
  final bool? supportsGotoTargetsRequest;

  /// The debug adapter supports breakpoints that break execution after a
  /// specified number of hits.
  final bool? supportsHitConditionalBreakpoints;

  /// The debug adapter supports adding breakpoints based on instruction
  /// references.
  final bool? supportsInstructionBreakpoints;

  /// The debug adapter supports the 'loadedSources' request.
  final bool? supportsLoadedSourcesRequest;

  /// The debug adapter supports logpoints by interpreting the 'logMessage'
  /// attribute of the SourceBreakpoint.
  final bool? supportsLogPoints;

  /// The debug adapter supports the 'modules' request.
  final bool? supportsModulesRequest;

  /// The debug adapter supports the 'readMemory' request.
  final bool? supportsReadMemoryRequest;

  /// The debug adapter supports restarting a frame.
  final bool? supportsRestartFrame;

  /// The debug adapter supports the 'restart' request. In this case a client
  /// should not implement 'restart' by terminating and relaunching the adapter
  /// but by calling the RestartRequest.
  final bool? supportsRestartRequest;

  /// The debug adapter supports the 'setExpression' request.
  final bool? supportsSetExpression;

  /// The debug adapter supports setting a variable to a value.
  final bool? supportsSetVariable;

  /// The debug adapter supports stepping back via the 'stepBack' and
  /// 'reverseContinue' requests.
  final bool? supportsStepBack;

  /// The debug adapter supports the 'stepInTargets' request.
  final bool? supportsStepInTargetsRequest;

  /// The debug adapter supports stepping granularities (argument 'granularity')
  /// for the stepping requests.
  final bool? supportsSteppingGranularity;

  /// The debug adapter supports the 'terminate' request.
  final bool? supportsTerminateRequest;

  /// The debug adapter supports the 'terminateThreads' request.
  final bool? supportsTerminateThreadsRequest;

  /// The debug adapter supports a 'format' attribute on the stackTraceRequest,
  /// variablesRequest, and evaluateRequest.
  final bool? supportsValueFormattingOptions;

  static Capabilities fromJson(Map<String, Object?> obj) =>
      Capabilities.fromMap(obj);

  Capabilities({
    this.additionalModuleColumns,
    this.completionTriggerCharacters,
    this.exceptionBreakpointFilters,
    this.supportSuspendDebuggee,
    this.supportTerminateDebuggee,
    this.supportedChecksumAlgorithms,
    this.supportsBreakpointLocationsRequest,
    this.supportsCancelRequest,
    this.supportsClipboardContext,
    this.supportsCompletionsRequest,
    this.supportsConditionalBreakpoints,
    this.supportsConfigurationDoneRequest,
    this.supportsDataBreakpoints,
    this.supportsDelayedStackTraceLoading,
    this.supportsDisassembleRequest,
    this.supportsEvaluateForHovers,
    this.supportsExceptionFilterOptions,
    this.supportsExceptionInfoRequest,
    this.supportsExceptionOptions,
    this.supportsFunctionBreakpoints,
    this.supportsGotoTargetsRequest,
    this.supportsHitConditionalBreakpoints,
    this.supportsInstructionBreakpoints,
    this.supportsLoadedSourcesRequest,
    this.supportsLogPoints,
    this.supportsModulesRequest,
    this.supportsReadMemoryRequest,
    this.supportsRestartFrame,
    this.supportsRestartRequest,
    this.supportsSetExpression,
    this.supportsSetVariable,
    this.supportsStepBack,
    this.supportsStepInTargetsRequest,
    this.supportsSteppingGranularity,
    this.supportsTerminateRequest,
    this.supportsTerminateThreadsRequest,
    this.supportsValueFormattingOptions,
  });

  Capabilities.fromMap(Map<String, Object?> obj)
      : additionalModuleColumns = (obj['additionalModuleColumns'] as List?)
            ?.map((item) =>
                ColumnDescriptor.fromJson(item as Map<String, Object?>))
            .toList(),
        completionTriggerCharacters =
            (obj['completionTriggerCharacters'] as List?)
                ?.map((item) => item as String)
                .toList(),
        exceptionBreakpointFilters =
            (obj['exceptionBreakpointFilters'] as List?)
                ?.map((item) => ExceptionBreakpointsFilter.fromJson(
                    item as Map<String, Object?>))
                .toList(),
        supportSuspendDebuggee = obj['supportSuspendDebuggee'] as bool?,
        supportTerminateDebuggee = obj['supportTerminateDebuggee'] as bool?,
        supportedChecksumAlgorithms =
            (obj['supportedChecksumAlgorithms'] as List?)
                ?.map((item) => item as ChecksumAlgorithm)
                .toList(),
        supportsBreakpointLocationsRequest =
            obj['supportsBreakpointLocationsRequest'] as bool?,
        supportsCancelRequest = obj['supportsCancelRequest'] as bool?,
        supportsClipboardContext = obj['supportsClipboardContext'] as bool?,
        supportsCompletionsRequest = obj['supportsCompletionsRequest'] as bool?,
        supportsConditionalBreakpoints =
            obj['supportsConditionalBreakpoints'] as bool?,
        supportsConfigurationDoneRequest =
            obj['supportsConfigurationDoneRequest'] as bool?,
        supportsDataBreakpoints = obj['supportsDataBreakpoints'] as bool?,
        supportsDelayedStackTraceLoading =
            obj['supportsDelayedStackTraceLoading'] as bool?,
        supportsDisassembleRequest = obj['supportsDisassembleRequest'] as bool?,
        supportsEvaluateForHovers = obj['supportsEvaluateForHovers'] as bool?,
        supportsExceptionFilterOptions =
            obj['supportsExceptionFilterOptions'] as bool?,
        supportsExceptionInfoRequest =
            obj['supportsExceptionInfoRequest'] as bool?,
        supportsExceptionOptions = obj['supportsExceptionOptions'] as bool?,
        supportsFunctionBreakpoints =
            obj['supportsFunctionBreakpoints'] as bool?,
        supportsGotoTargetsRequest = obj['supportsGotoTargetsRequest'] as bool?,
        supportsHitConditionalBreakpoints =
            obj['supportsHitConditionalBreakpoints'] as bool?,
        supportsInstructionBreakpoints =
            obj['supportsInstructionBreakpoints'] as bool?,
        supportsLoadedSourcesRequest =
            obj['supportsLoadedSourcesRequest'] as bool?,
        supportsLogPoints = obj['supportsLogPoints'] as bool?,
        supportsModulesRequest = obj['supportsModulesRequest'] as bool?,
        supportsReadMemoryRequest = obj['supportsReadMemoryRequest'] as bool?,
        supportsRestartFrame = obj['supportsRestartFrame'] as bool?,
        supportsRestartRequest = obj['supportsRestartRequest'] as bool?,
        supportsSetExpression = obj['supportsSetExpression'] as bool?,
        supportsSetVariable = obj['supportsSetVariable'] as bool?,
        supportsStepBack = obj['supportsStepBack'] as bool?,
        supportsStepInTargetsRequest =
            obj['supportsStepInTargetsRequest'] as bool?,
        supportsSteppingGranularity =
            obj['supportsSteppingGranularity'] as bool?,
        supportsTerminateRequest = obj['supportsTerminateRequest'] as bool?,
        supportsTerminateThreadsRequest =
            obj['supportsTerminateThreadsRequest'] as bool?,
        supportsValueFormattingOptions =
            obj['supportsValueFormattingOptions'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['additionalModuleColumns'] is! List ||
        (obj['additionalModuleColumns']
            .any((item) => !ColumnDescriptor.canParse(item))))) {
      return false;
    }
    if ((obj['completionTriggerCharacters'] is! List ||
        (obj['completionTriggerCharacters'].any((item) => item is! String)))) {
      return false;
    }
    if ((obj['exceptionBreakpointFilters'] is! List ||
        (obj['exceptionBreakpointFilters']
            .any((item) => !ExceptionBreakpointsFilter.canParse(item))))) {
      return false;
    }
    if (obj['supportSuspendDebuggee'] is! bool?) {
      return false;
    }
    if (obj['supportTerminateDebuggee'] is! bool?) {
      return false;
    }
    if ((obj['supportedChecksumAlgorithms'] is! List ||
        (obj['supportedChecksumAlgorithms']
            .any((item) => item is! ChecksumAlgorithm)))) {
      return false;
    }
    if (obj['supportsBreakpointLocationsRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsCancelRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsClipboardContext'] is! bool?) {
      return false;
    }
    if (obj['supportsCompletionsRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsConditionalBreakpoints'] is! bool?) {
      return false;
    }
    if (obj['supportsConfigurationDoneRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsDataBreakpoints'] is! bool?) {
      return false;
    }
    if (obj['supportsDelayedStackTraceLoading'] is! bool?) {
      return false;
    }
    if (obj['supportsDisassembleRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsEvaluateForHovers'] is! bool?) {
      return false;
    }
    if (obj['supportsExceptionFilterOptions'] is! bool?) {
      return false;
    }
    if (obj['supportsExceptionInfoRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsExceptionOptions'] is! bool?) {
      return false;
    }
    if (obj['supportsFunctionBreakpoints'] is! bool?) {
      return false;
    }
    if (obj['supportsGotoTargetsRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsHitConditionalBreakpoints'] is! bool?) {
      return false;
    }
    if (obj['supportsInstructionBreakpoints'] is! bool?) {
      return false;
    }
    if (obj['supportsLoadedSourcesRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsLogPoints'] is! bool?) {
      return false;
    }
    if (obj['supportsModulesRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsReadMemoryRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsRestartFrame'] is! bool?) {
      return false;
    }
    if (obj['supportsRestartRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsSetExpression'] is! bool?) {
      return false;
    }
    if (obj['supportsSetVariable'] is! bool?) {
      return false;
    }
    if (obj['supportsStepBack'] is! bool?) {
      return false;
    }
    if (obj['supportsStepInTargetsRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsSteppingGranularity'] is! bool?) {
      return false;
    }
    if (obj['supportsTerminateRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsTerminateThreadsRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsValueFormattingOptions'] is! bool?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (additionalModuleColumns != null)
          'additionalModuleColumns': additionalModuleColumns,
        if (completionTriggerCharacters != null)
          'completionTriggerCharacters': completionTriggerCharacters,
        if (exceptionBreakpointFilters != null)
          'exceptionBreakpointFilters': exceptionBreakpointFilters,
        if (supportSuspendDebuggee != null)
          'supportSuspendDebuggee': supportSuspendDebuggee,
        if (supportTerminateDebuggee != null)
          'supportTerminateDebuggee': supportTerminateDebuggee,
        if (supportedChecksumAlgorithms != null)
          'supportedChecksumAlgorithms': supportedChecksumAlgorithms,
        if (supportsBreakpointLocationsRequest != null)
          'supportsBreakpointLocationsRequest':
              supportsBreakpointLocationsRequest,
        if (supportsCancelRequest != null)
          'supportsCancelRequest': supportsCancelRequest,
        if (supportsClipboardContext != null)
          'supportsClipboardContext': supportsClipboardContext,
        if (supportsCompletionsRequest != null)
          'supportsCompletionsRequest': supportsCompletionsRequest,
        if (supportsConditionalBreakpoints != null)
          'supportsConditionalBreakpoints': supportsConditionalBreakpoints,
        if (supportsConfigurationDoneRequest != null)
          'supportsConfigurationDoneRequest': supportsConfigurationDoneRequest,
        if (supportsDataBreakpoints != null)
          'supportsDataBreakpoints': supportsDataBreakpoints,
        if (supportsDelayedStackTraceLoading != null)
          'supportsDelayedStackTraceLoading': supportsDelayedStackTraceLoading,
        if (supportsDisassembleRequest != null)
          'supportsDisassembleRequest': supportsDisassembleRequest,
        if (supportsEvaluateForHovers != null)
          'supportsEvaluateForHovers': supportsEvaluateForHovers,
        if (supportsExceptionFilterOptions != null)
          'supportsExceptionFilterOptions': supportsExceptionFilterOptions,
        if (supportsExceptionInfoRequest != null)
          'supportsExceptionInfoRequest': supportsExceptionInfoRequest,
        if (supportsExceptionOptions != null)
          'supportsExceptionOptions': supportsExceptionOptions,
        if (supportsFunctionBreakpoints != null)
          'supportsFunctionBreakpoints': supportsFunctionBreakpoints,
        if (supportsGotoTargetsRequest != null)
          'supportsGotoTargetsRequest': supportsGotoTargetsRequest,
        if (supportsHitConditionalBreakpoints != null)
          'supportsHitConditionalBreakpoints':
              supportsHitConditionalBreakpoints,
        if (supportsInstructionBreakpoints != null)
          'supportsInstructionBreakpoints': supportsInstructionBreakpoints,
        if (supportsLoadedSourcesRequest != null)
          'supportsLoadedSourcesRequest': supportsLoadedSourcesRequest,
        if (supportsLogPoints != null) 'supportsLogPoints': supportsLogPoints,
        if (supportsModulesRequest != null)
          'supportsModulesRequest': supportsModulesRequest,
        if (supportsReadMemoryRequest != null)
          'supportsReadMemoryRequest': supportsReadMemoryRequest,
        if (supportsRestartFrame != null)
          'supportsRestartFrame': supportsRestartFrame,
        if (supportsRestartRequest != null)
          'supportsRestartRequest': supportsRestartRequest,
        if (supportsSetExpression != null)
          'supportsSetExpression': supportsSetExpression,
        if (supportsSetVariable != null)
          'supportsSetVariable': supportsSetVariable,
        if (supportsStepBack != null) 'supportsStepBack': supportsStepBack,
        if (supportsStepInTargetsRequest != null)
          'supportsStepInTargetsRequest': supportsStepInTargetsRequest,
        if (supportsSteppingGranularity != null)
          'supportsSteppingGranularity': supportsSteppingGranularity,
        if (supportsTerminateRequest != null)
          'supportsTerminateRequest': supportsTerminateRequest,
        if (supportsTerminateThreadsRequest != null)
          'supportsTerminateThreadsRequest': supportsTerminateThreadsRequest,
        if (supportsValueFormattingOptions != null)
          'supportsValueFormattingOptions': supportsValueFormattingOptions,
      };
}

/// The checksum of an item calculated by the specified algorithm.
class Checksum {
  /// The algorithm used to calculate this checksum.
  final ChecksumAlgorithm algorithm;

  /// Value of the checksum.
  final String checksum;

  static Checksum fromJson(Map<String, Object?> obj) => Checksum.fromMap(obj);

  Checksum({
    required this.algorithm,
    required this.checksum,
  });

  Checksum.fromMap(Map<String, Object?> obj)
      : algorithm = obj['algorithm'] as ChecksumAlgorithm,
        checksum = obj['checksum'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['algorithm'] is! ChecksumAlgorithm) {
      return false;
    }
    if (obj['checksum'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'algorithm': algorithm,
        'checksum': checksum,
      };
}

/// Names of checksum algorithms that may be supported by a debug adapter.
typedef ChecksumAlgorithm = String;

/// A ColumnDescriptor specifies what module attribute to show in a column of
/// the ModulesView, how to format it,
/// and what the column's label should be.
/// It is only used if the underlying UI actually supports this level of
/// customization.
class ColumnDescriptor {
  /// Name of the attribute rendered in this column.
  final String attributeName;

  /// Format to use for the rendered values in this column. TBD how the format
  /// strings looks like.
  final String? format;

  /// Header UI label of column.
  final String label;

  /// Datatype of values in this column.  Defaults to 'string' if not specified.
  final String? type;

  /// Width of this column in characters (hint only).
  final int? width;

  static ColumnDescriptor fromJson(Map<String, Object?> obj) =>
      ColumnDescriptor.fromMap(obj);

  ColumnDescriptor({
    required this.attributeName,
    this.format,
    required this.label,
    this.type,
    this.width,
  });

  ColumnDescriptor.fromMap(Map<String, Object?> obj)
      : attributeName = obj['attributeName'] as String,
        format = obj['format'] as String?,
        label = obj['label'] as String,
        type = obj['type'] as String?,
        width = obj['width'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['attributeName'] is! String) {
      return false;
    }
    if (obj['format'] is! String?) {
      return false;
    }
    if (obj['label'] is! String) {
      return false;
    }
    if (obj['type'] is! String?) {
      return false;
    }
    if (obj['width'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'attributeName': attributeName,
        if (format != null) 'format': format,
        'label': label,
        if (type != null) 'type': type,
        if (width != null) 'width': width,
      };
}

/// CompletionItems are the suggestions returned from the CompletionsRequest.
class CompletionItem {
  /// The label of this completion item. By default this is also the text that
  /// is inserted when selecting this completion.
  final String label;

  /// This value determines how many characters are overwritten by the
  /// completion text.
  /// If missing the value 0 is assumed which results in the completion text
  /// being inserted.
  final int? length;

  /// Determines the length of the new selection after the text has been
  /// inserted (or replaced).
  /// The selection can not extend beyond the bounds of the completion text.
  /// If omitted the length is assumed to be 0.
  final int? selectionLength;

  /// Determines the start of the new selection after the text has been inserted
  /// (or replaced).
  /// The start position must in the range 0 and length of the completion text.
  /// If omitted the selection starts at the end of the completion text.
  final int? selectionStart;

  /// A string that should be used when comparing this item with other items.
  /// When `falsy` the label is used.
  final String? sortText;

  /// This value determines the location (in the CompletionsRequest's 'text'
  /// attribute) where the completion text is added.
  /// If missing the text is added at the location specified by the
  /// CompletionsRequest's 'column' attribute.
  final int? start;

  /// If text is not falsy then it is inserted instead of the label.
  final String? text;

  /// The item's type. Typically the client uses this information to render the
  /// item in the UI with an icon.
  final CompletionItemType? type;

  static CompletionItem fromJson(Map<String, Object?> obj) =>
      CompletionItem.fromMap(obj);

  CompletionItem({
    required this.label,
    this.length,
    this.selectionLength,
    this.selectionStart,
    this.sortText,
    this.start,
    this.text,
    this.type,
  });

  CompletionItem.fromMap(Map<String, Object?> obj)
      : label = obj['label'] as String,
        length = obj['length'] as int?,
        selectionLength = obj['selectionLength'] as int?,
        selectionStart = obj['selectionStart'] as int?,
        sortText = obj['sortText'] as String?,
        start = obj['start'] as int?,
        text = obj['text'] as String?,
        type = obj['type'] as CompletionItemType?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['label'] is! String) {
      return false;
    }
    if (obj['length'] is! int?) {
      return false;
    }
    if (obj['selectionLength'] is! int?) {
      return false;
    }
    if (obj['selectionStart'] is! int?) {
      return false;
    }
    if (obj['sortText'] is! String?) {
      return false;
    }
    if (obj['start'] is! int?) {
      return false;
    }
    if (obj['text'] is! String?) {
      return false;
    }
    if (obj['type'] is! CompletionItemType?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'label': label,
        if (length != null) 'length': length,
        if (selectionLength != null) 'selectionLength': selectionLength,
        if (selectionStart != null) 'selectionStart': selectionStart,
        if (sortText != null) 'sortText': sortText,
        if (start != null) 'start': start,
        if (text != null) 'text': text,
        if (type != null) 'type': type,
      };
}

/// Some predefined types for the CompletionItem. Please note that not all
/// clients have specific icons for all of them.
typedef CompletionItemType = String;

/// Arguments for 'completions' request.
class CompletionsArguments extends RequestArguments {
  /// The character position for which to determine the completion proposals.
  final int column;

  /// Returns completions in the scope of this stack frame. If not specified,
  /// the completions are returned for the global scope.
  final int? frameId;

  /// An optional line for which to determine the completion proposals. If
  /// missing the first line of the text is assumed.
  final int? line;

  /// One or more source lines. Typically this is the text a user has typed into
  /// the debug console before he asked for completion.
  final String text;

  static CompletionsArguments fromJson(Map<String, Object?> obj) =>
      CompletionsArguments.fromMap(obj);

  CompletionsArguments({
    required this.column,
    this.frameId,
    this.line,
    required this.text,
  });

  CompletionsArguments.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int,
        frameId = obj['frameId'] as int?,
        line = obj['line'] as int?,
        text = obj['text'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int) {
      return false;
    }
    if (obj['frameId'] is! int?) {
      return false;
    }
    if (obj['line'] is! int?) {
      return false;
    }
    if (obj['text'] is! String) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'column': column,
        if (frameId != null) 'frameId': frameId,
        if (line != null) 'line': line,
        'text': text,
      };
}

/// Response to 'completions' request.
class CompletionsResponse extends Response {
  static CompletionsResponse fromJson(Map<String, Object?> obj) =>
      CompletionsResponse.fromMap(obj);

  CompletionsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  CompletionsResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'configurationDone' request.
class ConfigurationDoneArguments extends RequestArguments {
  static ConfigurationDoneArguments fromJson(Map<String, Object?> obj) =>
      ConfigurationDoneArguments.fromMap(obj);

  ConfigurationDoneArguments();

  ConfigurationDoneArguments.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {};
}

/// Response to 'configurationDone' request. This is just an acknowledgement, so
/// no body field is required.
class ConfigurationDoneResponse extends Response {
  static ConfigurationDoneResponse fromJson(Map<String, Object?> obj) =>
      ConfigurationDoneResponse.fromMap(obj);

  ConfigurationDoneResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ConfigurationDoneResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'continue' request.
class ContinueArguments extends RequestArguments {
  /// Continue execution for the specified thread (if possible).
  /// If the backend cannot continue on a single thread but will continue on all
  /// threads, it should set the 'allThreadsContinued' attribute in the response
  /// to true.
  final int threadId;

  static ContinueArguments fromJson(Map<String, Object?> obj) =>
      ContinueArguments.fromMap(obj);

  ContinueArguments({
    required this.threadId,
  });

  ContinueArguments.fromMap(Map<String, Object?> obj)
      : threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'threadId': threadId,
      };
}

/// Response to 'continue' request.
class ContinueResponse extends Response {
  static ContinueResponse fromJson(Map<String, Object?> obj) =>
      ContinueResponse.fromMap(obj);

  ContinueResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ContinueResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Properties of a data breakpoint passed to the setDataBreakpoints request.
class DataBreakpoint {
  /// The access type of the data.
  final DataBreakpointAccessType? accessType;

  /// An optional expression for conditional breakpoints.
  final String? condition;

  /// An id representing the data. This id is returned from the
  /// dataBreakpointInfo request.
  final String dataId;

  /// An optional expression that controls how many hits of the breakpoint are
  /// ignored.
  /// The backend is expected to interpret the expression as needed.
  final String? hitCondition;

  static DataBreakpoint fromJson(Map<String, Object?> obj) =>
      DataBreakpoint.fromMap(obj);

  DataBreakpoint({
    this.accessType,
    this.condition,
    required this.dataId,
    this.hitCondition,
  });

  DataBreakpoint.fromMap(Map<String, Object?> obj)
      : accessType = obj['accessType'] as DataBreakpointAccessType?,
        condition = obj['condition'] as String?,
        dataId = obj['dataId'] as String,
        hitCondition = obj['hitCondition'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['accessType'] is! DataBreakpointAccessType?) {
      return false;
    }
    if (obj['condition'] is! String?) {
      return false;
    }
    if (obj['dataId'] is! String) {
      return false;
    }
    if (obj['hitCondition'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (accessType != null) 'accessType': accessType,
        if (condition != null) 'condition': condition,
        'dataId': dataId,
        if (hitCondition != null) 'hitCondition': hitCondition,
      };
}

/// This enumeration defines all possible access types for data breakpoints.
typedef DataBreakpointAccessType = String;

/// Arguments for 'dataBreakpointInfo' request.
class DataBreakpointInfoArguments extends RequestArguments {
  /// The name of the Variable's child to obtain data breakpoint information
  /// for.
  /// If variablesReference isn’t provided, this can be an expression.
  final String name;

  /// Reference to the Variable container if the data breakpoint is requested
  /// for a child of the container.
  final int? variablesReference;

  static DataBreakpointInfoArguments fromJson(Map<String, Object?> obj) =>
      DataBreakpointInfoArguments.fromMap(obj);

  DataBreakpointInfoArguments({
    required this.name,
    this.variablesReference,
  });

  DataBreakpointInfoArguments.fromMap(Map<String, Object?> obj)
      : name = obj['name'] as String,
        variablesReference = obj['variablesReference'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['variablesReference'] is! int?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'name': name,
        if (variablesReference != null)
          'variablesReference': variablesReference,
      };
}

/// Response to 'dataBreakpointInfo' request.
class DataBreakpointInfoResponse extends Response {
  static DataBreakpointInfoResponse fromJson(Map<String, Object?> obj) =>
      DataBreakpointInfoResponse.fromMap(obj);

  DataBreakpointInfoResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  DataBreakpointInfoResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'disassemble' request.
class DisassembleArguments extends RequestArguments {
  /// Number of instructions to disassemble starting at the specified location
  /// and offset.
  /// An adapter must return exactly this number of instructions - any
  /// unavailable instructions should be replaced with an implementation-defined
  /// 'invalid instruction' value.
  final int instructionCount;

  /// Optional offset (in instructions) to be applied after the byte offset (if
  /// any) before disassembling. Can be negative.
  final int? instructionOffset;

  /// Memory reference to the base location containing the instructions to
  /// disassemble.
  final String memoryReference;

  /// Optional offset (in bytes) to be applied to the reference location before
  /// disassembling. Can be negative.
  final int? offset;

  /// If true, the adapter should attempt to resolve memory addresses and other
  /// values to symbolic names.
  final bool? resolveSymbols;

  static DisassembleArguments fromJson(Map<String, Object?> obj) =>
      DisassembleArguments.fromMap(obj);

  DisassembleArguments({
    required this.instructionCount,
    this.instructionOffset,
    required this.memoryReference,
    this.offset,
    this.resolveSymbols,
  });

  DisassembleArguments.fromMap(Map<String, Object?> obj)
      : instructionCount = obj['instructionCount'] as int,
        instructionOffset = obj['instructionOffset'] as int?,
        memoryReference = obj['memoryReference'] as String,
        offset = obj['offset'] as int?,
        resolveSymbols = obj['resolveSymbols'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['instructionCount'] is! int) {
      return false;
    }
    if (obj['instructionOffset'] is! int?) {
      return false;
    }
    if (obj['memoryReference'] is! String) {
      return false;
    }
    if (obj['offset'] is! int?) {
      return false;
    }
    if (obj['resolveSymbols'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'instructionCount': instructionCount,
        if (instructionOffset != null) 'instructionOffset': instructionOffset,
        'memoryReference': memoryReference,
        if (offset != null) 'offset': offset,
        if (resolveSymbols != null) 'resolveSymbols': resolveSymbols,
      };
}

/// Response to 'disassemble' request.
class DisassembleResponse extends Response {
  static DisassembleResponse fromJson(Map<String, Object?> obj) =>
      DisassembleResponse.fromMap(obj);

  DisassembleResponse({
    Map<String, Object?>? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  DisassembleResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>?) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Represents a single disassembled instruction.
class DisassembledInstruction {
  /// The address of the instruction. Treated as a hex value if prefixed with
  /// '0x', or as a decimal value otherwise.
  final String address;

  /// The column within the line that corresponds to this instruction, if any.
  final int? column;

  /// The end column of the range that corresponds to this instruction, if any.
  final int? endColumn;

  /// The end line of the range that corresponds to this instruction, if any.
  final int? endLine;

  /// Text representing the instruction and its operands, in an
  /// implementation-defined format.
  final String instruction;

  /// Optional raw bytes representing the instruction and its operands, in an
  /// implementation-defined format.
  final String? instructionBytes;

  /// The line within the source location that corresponds to this instruction,
  /// if any.
  final int? line;

  /// Source location that corresponds to this instruction, if any.
  /// Should always be set (if available) on the first instruction returned,
  /// but can be omitted afterwards if this instruction maps to the same source
  /// file as the previous instruction.
  final Source? location;

  /// Name of the symbol that corresponds with the location of this instruction,
  /// if any.
  final String? symbol;

  static DisassembledInstruction fromJson(Map<String, Object?> obj) =>
      DisassembledInstruction.fromMap(obj);

  DisassembledInstruction({
    required this.address,
    this.column,
    this.endColumn,
    this.endLine,
    required this.instruction,
    this.instructionBytes,
    this.line,
    this.location,
    this.symbol,
  });

  DisassembledInstruction.fromMap(Map<String, Object?> obj)
      : address = obj['address'] as String,
        column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        instruction = obj['instruction'] as String,
        instructionBytes = obj['instructionBytes'] as String?,
        line = obj['line'] as int?,
        location = obj['location'] == null
            ? null
            : Source.fromJson(obj['location'] as Map<String, Object?>),
        symbol = obj['symbol'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['address'] is! String) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['instruction'] is! String) {
      return false;
    }
    if (obj['instructionBytes'] is! String?) {
      return false;
    }
    if (obj['line'] is! int?) {
      return false;
    }
    if (!Source.canParse(obj['location'])) {
      return false;
    }
    if (obj['symbol'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'address': address,
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'instruction': instruction,
        if (instructionBytes != null) 'instructionBytes': instructionBytes,
        if (line != null) 'line': line,
        if (location != null) 'location': location,
        if (symbol != null) 'symbol': symbol,
      };
}

/// Arguments for 'disconnect' request.
class DisconnectArguments extends RequestArguments {
  /// A value of true indicates that this 'disconnect' request is part of a
  /// restart sequence.
  final bool? restart;

  /// Indicates whether the debuggee should stay suspended when the debugger is
  /// disconnected.
  /// If unspecified, the debuggee should resume execution.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportSuspendDebuggee' is true.
  final bool? suspendDebuggee;

  /// Indicates whether the debuggee should be terminated when the debugger is
  /// disconnected.
  /// If unspecified, the debug adapter is free to do whatever it thinks is
  /// best.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportTerminateDebuggee' is true.
  final bool? terminateDebuggee;

  static DisconnectArguments fromJson(Map<String, Object?> obj) =>
      DisconnectArguments.fromMap(obj);

  DisconnectArguments({
    this.restart,
    this.suspendDebuggee,
    this.terminateDebuggee,
  });

  DisconnectArguments.fromMap(Map<String, Object?> obj)
      : restart = obj['restart'] as bool?,
        suspendDebuggee = obj['suspendDebuggee'] as bool?,
        terminateDebuggee = obj['terminateDebuggee'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['restart'] is! bool?) {
      return false;
    }
    if (obj['suspendDebuggee'] is! bool?) {
      return false;
    }
    if (obj['terminateDebuggee'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (restart != null) 'restart': restart,
        if (suspendDebuggee != null) 'suspendDebuggee': suspendDebuggee,
        if (terminateDebuggee != null) 'terminateDebuggee': terminateDebuggee,
      };
}

/// Response to 'disconnect' request. This is just an acknowledgement, so no
/// body field is required.
class DisconnectResponse extends Response {
  static DisconnectResponse fromJson(Map<String, Object?> obj) =>
      DisconnectResponse.fromMap(obj);

  DisconnectResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  DisconnectResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// On error (whenever 'success' is false), the body can provide more details.
class ErrorResponse extends Response {
  static ErrorResponse fromJson(Map<String, Object?> obj) =>
      ErrorResponse.fromMap(obj);

  ErrorResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ErrorResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'evaluate' request.
class EvaluateArguments extends RequestArguments {
  /// The context in which the evaluate request is run.
  final String? context;

  /// The expression to evaluate.
  final String expression;

  /// Specifies details on how to format the Evaluate result.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsValueFormattingOptions' is true.
  final ValueFormat? format;

  /// Evaluate the expression in the scope of this stack frame. If not
  /// specified, the expression is evaluated in the global scope.
  final int? frameId;

  static EvaluateArguments fromJson(Map<String, Object?> obj) =>
      EvaluateArguments.fromMap(obj);

  EvaluateArguments({
    this.context,
    required this.expression,
    this.format,
    this.frameId,
  });

  EvaluateArguments.fromMap(Map<String, Object?> obj)
      : context = obj['context'] as String?,
        expression = obj['expression'] as String,
        format = obj['format'] == null
            ? null
            : ValueFormat.fromJson(obj['format'] as Map<String, Object?>),
        frameId = obj['frameId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['context'] is! String?) {
      return false;
    }
    if (obj['expression'] is! String) {
      return false;
    }
    if (!ValueFormat.canParse(obj['format'])) {
      return false;
    }
    if (obj['frameId'] is! int?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (context != null) 'context': context,
        'expression': expression,
        if (format != null) 'format': format,
        if (frameId != null) 'frameId': frameId,
      };
}

/// Response to 'evaluate' request.
class EvaluateResponse extends Response {
  static EvaluateResponse fromJson(Map<String, Object?> obj) =>
      EvaluateResponse.fromMap(obj);

  EvaluateResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  EvaluateResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A debug adapter initiated event.
class Event extends ProtocolMessage {
  /// Event-specific information.
  final Object? body;

  /// Type of event.
  final String event;

  static Event fromJson(Map<String, Object?> obj) => Event.fromMap(obj);

  Event({
    this.body,
    required this.event,
    required int seq,
  }) : super(
          seq: seq,
          type: 'event',
        );

  Event.fromMap(Map<String, Object?> obj)
      : body = obj['body'],
        event = obj['event'] as String,
        super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['event'] is! String) {
      return false;
    }
    if (obj['type'] is! String) {
      return false;
    }
    return ProtocolMessage.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
        if (body != null) 'body': body,
        'event': event,
      };
}

/// This enumeration defines all possible conditions when a thrown exception
/// should result in a break.
/// never: never breaks,
/// always: always breaks,
/// unhandled: breaks when exception unhandled,
/// userUnhandled: breaks if the exception is not handled by user code.
typedef ExceptionBreakMode = String;

/// An ExceptionBreakpointsFilter is shown in the UI as an filter option for
/// configuring how exceptions are dealt with.
class ExceptionBreakpointsFilter {
  /// An optional help text providing information about the condition. This
  /// string is shown as the placeholder text for a text box and must be
  /// translated.
  final String? conditionDescription;

  /// Initial value of the filter option. If not specified a value 'false' is
  /// assumed.
  final bool? defaultValue;

  /// An optional help text providing additional information about the exception
  /// filter. This string is typically shown as a hover and must be translated.
  final String? description;

  /// The internal ID of the filter option. This value is passed to the
  /// 'setExceptionBreakpoints' request.
  final String filter;

  /// The name of the filter option. This will be shown in the UI.
  final String label;

  /// Controls whether a condition can be specified for this filter option. If
  /// false or missing, a condition can not be set.
  final bool? supportsCondition;

  static ExceptionBreakpointsFilter fromJson(Map<String, Object?> obj) =>
      ExceptionBreakpointsFilter.fromMap(obj);

  ExceptionBreakpointsFilter({
    this.conditionDescription,
    this.defaultValue,
    this.description,
    required this.filter,
    required this.label,
    this.supportsCondition,
  });

  ExceptionBreakpointsFilter.fromMap(Map<String, Object?> obj)
      : conditionDescription = obj['conditionDescription'] as String?,
        defaultValue = obj['default'] as bool?,
        description = obj['description'] as String?,
        filter = obj['filter'] as String,
        label = obj['label'] as String,
        supportsCondition = obj['supportsCondition'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['conditionDescription'] is! String?) {
      return false;
    }
    if (obj['default'] is! bool?) {
      return false;
    }
    if (obj['description'] is! String?) {
      return false;
    }
    if (obj['filter'] is! String) {
      return false;
    }
    if (obj['label'] is! String) {
      return false;
    }
    if (obj['supportsCondition'] is! bool?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (conditionDescription != null)
          'conditionDescription': conditionDescription,
        if (defaultValue != null) 'default': defaultValue,
        if (description != null) 'description': description,
        'filter': filter,
        'label': label,
        if (supportsCondition != null) 'supportsCondition': supportsCondition,
      };
}

/// Detailed information about an exception that has occurred.
class ExceptionDetails {
  /// Optional expression that can be evaluated in the current scope to obtain
  /// the exception object.
  final String? evaluateName;

  /// Fully-qualified type name of the exception object.
  final String? fullTypeName;

  /// Details of the exception contained by this exception, if any.
  final List<ExceptionDetails>? innerException;

  /// Message contained in the exception.
  final String? message;

  /// Stack trace at the time the exception was thrown.
  final String? stackTrace;

  /// Short type name of the exception object.
  final String? typeName;

  static ExceptionDetails fromJson(Map<String, Object?> obj) =>
      ExceptionDetails.fromMap(obj);

  ExceptionDetails({
    this.evaluateName,
    this.fullTypeName,
    this.innerException,
    this.message,
    this.stackTrace,
    this.typeName,
  });

  ExceptionDetails.fromMap(Map<String, Object?> obj)
      : evaluateName = obj['evaluateName'] as String?,
        fullTypeName = obj['fullTypeName'] as String?,
        innerException = (obj['innerException'] as List?)
            ?.map((item) =>
                ExceptionDetails.fromJson(item as Map<String, Object?>))
            .toList(),
        message = obj['message'] as String?,
        stackTrace = obj['stackTrace'] as String?,
        typeName = obj['typeName'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['evaluateName'] is! String?) {
      return false;
    }
    if (obj['fullTypeName'] is! String?) {
      return false;
    }
    if ((obj['innerException'] is! List ||
        (obj['innerException']
            .any((item) => !ExceptionDetails.canParse(item))))) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['stackTrace'] is! String?) {
      return false;
    }
    if (obj['typeName'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (evaluateName != null) 'evaluateName': evaluateName,
        if (fullTypeName != null) 'fullTypeName': fullTypeName,
        if (innerException != null) 'innerException': innerException,
        if (message != null) 'message': message,
        if (stackTrace != null) 'stackTrace': stackTrace,
        if (typeName != null) 'typeName': typeName,
      };
}

/// An ExceptionFilterOptions is used to specify an exception filter together
/// with a condition for the setExceptionsFilter request.
class ExceptionFilterOptions {
  /// An optional expression for conditional exceptions.
  /// The exception will break into the debugger if the result of the condition
  /// is true.
  final String? condition;

  /// ID of an exception filter returned by the 'exceptionBreakpointFilters'
  /// capability.
  final String filterId;

  static ExceptionFilterOptions fromJson(Map<String, Object?> obj) =>
      ExceptionFilterOptions.fromMap(obj);

  ExceptionFilterOptions({
    this.condition,
    required this.filterId,
  });

  ExceptionFilterOptions.fromMap(Map<String, Object?> obj)
      : condition = obj['condition'] as String?,
        filterId = obj['filterId'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['condition'] is! String?) {
      return false;
    }
    if (obj['filterId'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (condition != null) 'condition': condition,
        'filterId': filterId,
      };
}

/// Arguments for 'exceptionInfo' request.
class ExceptionInfoArguments extends RequestArguments {
  /// Thread for which exception information should be retrieved.
  final int threadId;

  static ExceptionInfoArguments fromJson(Map<String, Object?> obj) =>
      ExceptionInfoArguments.fromMap(obj);

  ExceptionInfoArguments({
    required this.threadId,
  });

  ExceptionInfoArguments.fromMap(Map<String, Object?> obj)
      : threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'threadId': threadId,
      };
}

/// Response to 'exceptionInfo' request.
class ExceptionInfoResponse extends Response {
  static ExceptionInfoResponse fromJson(Map<String, Object?> obj) =>
      ExceptionInfoResponse.fromMap(obj);

  ExceptionInfoResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ExceptionInfoResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// An ExceptionOptions assigns configuration options to a set of exceptions.
class ExceptionOptions {
  /// Condition when a thrown exception should result in a break.
  final ExceptionBreakMode breakMode;

  /// A path that selects a single or multiple exceptions in a tree. If 'path'
  /// is missing, the whole tree is selected.
  /// By convention the first segment of the path is a category that is used to
  /// group exceptions in the UI.
  final List<ExceptionPathSegment>? path;

  static ExceptionOptions fromJson(Map<String, Object?> obj) =>
      ExceptionOptions.fromMap(obj);

  ExceptionOptions({
    required this.breakMode,
    this.path,
  });

  ExceptionOptions.fromMap(Map<String, Object?> obj)
      : breakMode = obj['breakMode'] as ExceptionBreakMode,
        path = (obj['path'] as List?)
            ?.map((item) =>
                ExceptionPathSegment.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['breakMode'] is! ExceptionBreakMode) {
      return false;
    }
    if ((obj['path'] is! List ||
        (obj['path'].any((item) => !ExceptionPathSegment.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakMode': breakMode,
        if (path != null) 'path': path,
      };
}

/// An ExceptionPathSegment represents a segment in a path that is used to match
/// leafs or nodes in a tree of exceptions.
/// If a segment consists of more than one name, it matches the names provided
/// if 'negate' is false or missing or
/// it matches anything except the names provided if 'negate' is true.
class ExceptionPathSegment {
  /// Depending on the value of 'negate' the names that should match or not
  /// match.
  final List<String> names;

  /// If false or missing this segment matches the names provided, otherwise it
  /// matches anything except the names provided.
  final bool? negate;

  static ExceptionPathSegment fromJson(Map<String, Object?> obj) =>
      ExceptionPathSegment.fromMap(obj);

  ExceptionPathSegment({
    required this.names,
    this.negate,
  });

  ExceptionPathSegment.fromMap(Map<String, Object?> obj)
      : names = (obj['names'] as List).map((item) => item as String).toList(),
        negate = obj['negate'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['names'] is! List ||
        (obj['names'].any((item) => item is! String)))) {
      return false;
    }
    if (obj['negate'] is! bool?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'names': names,
        if (negate != null) 'negate': negate,
      };
}

/// Properties of a breakpoint passed to the setFunctionBreakpoints request.
class FunctionBreakpoint {
  /// An optional expression for conditional breakpoints.
  /// It is only honored by a debug adapter if the capability
  /// 'supportsConditionalBreakpoints' is true.
  final String? condition;

  /// An optional expression that controls how many hits of the breakpoint are
  /// ignored.
  /// The backend is expected to interpret the expression as needed.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsHitConditionalBreakpoints' is true.
  final String? hitCondition;

  /// The name of the function.
  final String name;

  static FunctionBreakpoint fromJson(Map<String, Object?> obj) =>
      FunctionBreakpoint.fromMap(obj);

  FunctionBreakpoint({
    this.condition,
    this.hitCondition,
    required this.name,
  });

  FunctionBreakpoint.fromMap(Map<String, Object?> obj)
      : condition = obj['condition'] as String?,
        hitCondition = obj['hitCondition'] as String?,
        name = obj['name'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['condition'] is! String?) {
      return false;
    }
    if (obj['hitCondition'] is! String?) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (condition != null) 'condition': condition,
        if (hitCondition != null) 'hitCondition': hitCondition,
        'name': name,
      };
}

/// Arguments for 'goto' request.
class GotoArguments extends RequestArguments {
  /// The location where the debuggee will continue to run.
  final int targetId;

  /// Set the goto target for this thread.
  final int threadId;

  static GotoArguments fromJson(Map<String, Object?> obj) =>
      GotoArguments.fromMap(obj);

  GotoArguments({
    required this.targetId,
    required this.threadId,
  });

  GotoArguments.fromMap(Map<String, Object?> obj)
      : targetId = obj['targetId'] as int,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['targetId'] is! int) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'targetId': targetId,
        'threadId': threadId,
      };
}

/// Response to 'goto' request. This is just an acknowledgement, so no body
/// field is required.
class GotoResponse extends Response {
  static GotoResponse fromJson(Map<String, Object?> obj) =>
      GotoResponse.fromMap(obj);

  GotoResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  GotoResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A GotoTarget describes a code location that can be used as a target in the
/// 'goto' request.
/// The possible goto targets can be determined via the 'gotoTargets' request.
class GotoTarget {
  /// An optional column of the goto target.
  final int? column;

  /// An optional end column of the range covered by the goto target.
  final int? endColumn;

  /// An optional end line of the range covered by the goto target.
  final int? endLine;

  /// Unique identifier for a goto target. This is used in the goto request.
  final int id;

  /// Optional memory reference for the instruction pointer value represented by
  /// this target.
  final String? instructionPointerReference;

  /// The name of the goto target (shown in the UI).
  final String label;

  /// The line of the goto target.
  final int line;

  static GotoTarget fromJson(Map<String, Object?> obj) =>
      GotoTarget.fromMap(obj);

  GotoTarget({
    this.column,
    this.endColumn,
    this.endLine,
    required this.id,
    this.instructionPointerReference,
    required this.label,
    required this.line,
  });

  GotoTarget.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        id = obj['id'] as int,
        instructionPointerReference =
            obj['instructionPointerReference'] as String?,
        label = obj['label'] as String,
        line = obj['line'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['id'] is! int) {
      return false;
    }
    if (obj['instructionPointerReference'] is! String?) {
      return false;
    }
    if (obj['label'] is! String) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'id': id,
        if (instructionPointerReference != null)
          'instructionPointerReference': instructionPointerReference,
        'label': label,
        'line': line,
      };
}

/// Arguments for 'gotoTargets' request.
class GotoTargetsArguments extends RequestArguments {
  /// An optional column location for which the goto targets are determined.
  final int? column;

  /// The line location for which the goto targets are determined.
  final int line;

  /// The source location for which the goto targets are determined.
  final Source source;

  static GotoTargetsArguments fromJson(Map<String, Object?> obj) =>
      GotoTargetsArguments.fromMap(obj);

  GotoTargetsArguments({
    this.column,
    required this.line,
    required this.source,
  });

  GotoTargetsArguments.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        line = obj['line'] as int,
        source = Source.fromJson(obj['source'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        'line': line,
        'source': source,
      };
}

/// Response to 'gotoTargets' request.
class GotoTargetsResponse extends Response {
  static GotoTargetsResponse fromJson(Map<String, Object?> obj) =>
      GotoTargetsResponse.fromMap(obj);

  GotoTargetsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  GotoTargetsResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'initialize' request.
class InitializeRequestArguments extends RequestArguments {
  /// The ID of the debug adapter.
  final String adapterID;

  /// The ID of the (frontend) client using this adapter.
  final String? clientID;

  /// The human readable name of the (frontend) client using this adapter.
  final String? clientName;

  /// If true all column numbers are 1-based (default).
  final bool? columnsStartAt1;

  /// If true all line numbers are 1-based (default).
  final bool? linesStartAt1;

  /// The ISO-639 locale of the (frontend) client using this adapter, e.g. en-US
  /// or de-CH.
  final String? locale;

  /// Determines in what format paths are specified. The default is 'path',
  /// which is the native format.
  final String? pathFormat;

  /// Client supports the invalidated event.
  final bool? supportsInvalidatedEvent;

  /// Client supports memory references.
  final bool? supportsMemoryReferences;

  /// Client supports progress reporting.
  final bool? supportsProgressReporting;

  /// Client supports the runInTerminal request.
  final bool? supportsRunInTerminalRequest;

  /// Client supports the paging of variables.
  final bool? supportsVariablePaging;

  /// Client supports the optional type attribute for variables.
  final bool? supportsVariableType;

  static InitializeRequestArguments fromJson(Map<String, Object?> obj) =>
      InitializeRequestArguments.fromMap(obj);

  InitializeRequestArguments({
    required this.adapterID,
    this.clientID,
    this.clientName,
    this.columnsStartAt1,
    this.linesStartAt1,
    this.locale,
    this.pathFormat,
    this.supportsInvalidatedEvent,
    this.supportsMemoryReferences,
    this.supportsProgressReporting,
    this.supportsRunInTerminalRequest,
    this.supportsVariablePaging,
    this.supportsVariableType,
  });

  InitializeRequestArguments.fromMap(Map<String, Object?> obj)
      : adapterID = obj['adapterID'] as String,
        clientID = obj['clientID'] as String?,
        clientName = obj['clientName'] as String?,
        columnsStartAt1 = obj['columnsStartAt1'] as bool?,
        linesStartAt1 = obj['linesStartAt1'] as bool?,
        locale = obj['locale'] as String?,
        pathFormat = obj['pathFormat'] as String?,
        supportsInvalidatedEvent = obj['supportsInvalidatedEvent'] as bool?,
        supportsMemoryReferences = obj['supportsMemoryReferences'] as bool?,
        supportsProgressReporting = obj['supportsProgressReporting'] as bool?,
        supportsRunInTerminalRequest =
            obj['supportsRunInTerminalRequest'] as bool?,
        supportsVariablePaging = obj['supportsVariablePaging'] as bool?,
        supportsVariableType = obj['supportsVariableType'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['adapterID'] is! String) {
      return false;
    }
    if (obj['clientID'] is! String?) {
      return false;
    }
    if (obj['clientName'] is! String?) {
      return false;
    }
    if (obj['columnsStartAt1'] is! bool?) {
      return false;
    }
    if (obj['linesStartAt1'] is! bool?) {
      return false;
    }
    if (obj['locale'] is! String?) {
      return false;
    }
    if (obj['pathFormat'] is! String?) {
      return false;
    }
    if (obj['supportsInvalidatedEvent'] is! bool?) {
      return false;
    }
    if (obj['supportsMemoryReferences'] is! bool?) {
      return false;
    }
    if (obj['supportsProgressReporting'] is! bool?) {
      return false;
    }
    if (obj['supportsRunInTerminalRequest'] is! bool?) {
      return false;
    }
    if (obj['supportsVariablePaging'] is! bool?) {
      return false;
    }
    if (obj['supportsVariableType'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'adapterID': adapterID,
        if (clientID != null) 'clientID': clientID,
        if (clientName != null) 'clientName': clientName,
        if (columnsStartAt1 != null) 'columnsStartAt1': columnsStartAt1,
        if (linesStartAt1 != null) 'linesStartAt1': linesStartAt1,
        if (locale != null) 'locale': locale,
        if (pathFormat != null) 'pathFormat': pathFormat,
        if (supportsInvalidatedEvent != null)
          'supportsInvalidatedEvent': supportsInvalidatedEvent,
        if (supportsMemoryReferences != null)
          'supportsMemoryReferences': supportsMemoryReferences,
        if (supportsProgressReporting != null)
          'supportsProgressReporting': supportsProgressReporting,
        if (supportsRunInTerminalRequest != null)
          'supportsRunInTerminalRequest': supportsRunInTerminalRequest,
        if (supportsVariablePaging != null)
          'supportsVariablePaging': supportsVariablePaging,
        if (supportsVariableType != null)
          'supportsVariableType': supportsVariableType,
      };
}

/// Response to 'initialize' request.
class InitializeResponse extends Response {
  static InitializeResponse fromJson(Map<String, Object?> obj) =>
      InitializeResponse.fromMap(obj);

  InitializeResponse({
    Capabilities? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  InitializeResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Capabilities.canParse(obj['body'])) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Properties of a breakpoint passed to the setInstructionBreakpoints request
class InstructionBreakpoint {
  /// An optional expression for conditional breakpoints.
  /// It is only honored by a debug adapter if the capability
  /// 'supportsConditionalBreakpoints' is true.
  final String? condition;

  /// An optional expression that controls how many hits of the breakpoint are
  /// ignored.
  /// The backend is expected to interpret the expression as needed.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsHitConditionalBreakpoints' is true.
  final String? hitCondition;

  /// The instruction reference of the breakpoint.
  /// This should be a memory or instruction pointer reference from an
  /// EvaluateResponse, Variable, StackFrame, GotoTarget, or Breakpoint.
  final String instructionReference;

  /// An optional offset from the instruction reference.
  /// This can be negative.
  final int? offset;

  static InstructionBreakpoint fromJson(Map<String, Object?> obj) =>
      InstructionBreakpoint.fromMap(obj);

  InstructionBreakpoint({
    this.condition,
    this.hitCondition,
    required this.instructionReference,
    this.offset,
  });

  InstructionBreakpoint.fromMap(Map<String, Object?> obj)
      : condition = obj['condition'] as String?,
        hitCondition = obj['hitCondition'] as String?,
        instructionReference = obj['instructionReference'] as String,
        offset = obj['offset'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['condition'] is! String?) {
      return false;
    }
    if (obj['hitCondition'] is! String?) {
      return false;
    }
    if (obj['instructionReference'] is! String) {
      return false;
    }
    if (obj['offset'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (condition != null) 'condition': condition,
        if (hitCondition != null) 'hitCondition': hitCondition,
        'instructionReference': instructionReference,
        if (offset != null) 'offset': offset,
      };
}

/// Logical areas that can be invalidated by the 'invalidated' event.
typedef InvalidatedAreas = String;

/// Arguments for 'launch' request. Additional attributes are implementation
/// specific.
class LaunchRequestArguments extends RequestArguments {
  /// Optional data from the previous, restarted session.
  /// The data is sent as the 'restart' attribute of the 'terminated' event.
  /// The client should leave the data intact.
  final Object? restart;

  /// If noDebug is true the launch request should launch the program without
  /// enabling debugging.
  final bool? noDebug;

  static LaunchRequestArguments fromJson(Map<String, Object?> obj) =>
      LaunchRequestArguments.fromMap(obj);

  LaunchRequestArguments({
    this.restart,
    this.noDebug,
  });

  LaunchRequestArguments.fromMap(Map<String, Object?> obj)
      : restart = obj['__restart'],
        noDebug = obj['noDebug'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['noDebug'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (restart != null) '__restart': restart,
        if (noDebug != null) 'noDebug': noDebug,
      };
}

/// Response to 'launch' request. This is just an acknowledgement, so no body
/// field is required.
class LaunchResponse extends Response {
  static LaunchResponse fromJson(Map<String, Object?> obj) =>
      LaunchResponse.fromMap(obj);

  LaunchResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  LaunchResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'loadedSources' request.
class LoadedSourcesArguments extends RequestArguments {
  static LoadedSourcesArguments fromJson(Map<String, Object?> obj) =>
      LoadedSourcesArguments.fromMap(obj);

  LoadedSourcesArguments();

  LoadedSourcesArguments.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {};
}

/// Response to 'loadedSources' request.
class LoadedSourcesResponse extends Response {
  static LoadedSourcesResponse fromJson(Map<String, Object?> obj) =>
      LoadedSourcesResponse.fromMap(obj);

  LoadedSourcesResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  LoadedSourcesResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A structured message object. Used to return errors from requests.
class Message {
  /// A format string for the message. Embedded variables have the form
  /// '{name}'.
  /// If variable name starts with an underscore character, the variable does
  /// not contain user data (PII) and can be safely used for telemetry purposes.
  final String format;

  /// Unique identifier for the message.
  final int id;

  /// If true send to telemetry.
  final bool? sendTelemetry;

  /// If true show user.
  final bool? showUser;

  /// An optional url where additional information about this message can be
  /// found.
  final String? url;

  /// An optional label that is presented to the user as the UI for opening the
  /// url.
  final String? urlLabel;

  /// An object used as a dictionary for looking up the variables in the format
  /// string.
  final Map<String, Object?>? variables;

  static Message fromJson(Map<String, Object?> obj) => Message.fromMap(obj);

  Message({
    required this.format,
    required this.id,
    this.sendTelemetry,
    this.showUser,
    this.url,
    this.urlLabel,
    this.variables,
  });

  Message.fromMap(Map<String, Object?> obj)
      : format = obj['format'] as String,
        id = obj['id'] as int,
        sendTelemetry = obj['sendTelemetry'] as bool?,
        showUser = obj['showUser'] as bool?,
        url = obj['url'] as String?,
        urlLabel = obj['urlLabel'] as String?,
        variables = obj['variables'] as Map<String, Object?>?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['format'] is! String) {
      return false;
    }
    if (obj['id'] is! int) {
      return false;
    }
    if (obj['sendTelemetry'] is! bool?) {
      return false;
    }
    if (obj['showUser'] is! bool?) {
      return false;
    }
    if (obj['url'] is! String?) {
      return false;
    }
    if (obj['urlLabel'] is! String?) {
      return false;
    }
    if (obj['variables'] is! Map<String, Object?>?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'format': format,
        'id': id,
        if (sendTelemetry != null) 'sendTelemetry': sendTelemetry,
        if (showUser != null) 'showUser': showUser,
        if (url != null) 'url': url,
        if (urlLabel != null) 'urlLabel': urlLabel,
        if (variables != null) 'variables': variables,
      };
}

/// A Module object represents a row in the modules view.
/// Two attributes are mandatory: an id identifies a module in the modules view
/// and is used in a ModuleEvent for identifying a module for adding, updating
/// or deleting.
/// The name is used to minimally render the module in the UI.
///
/// Additional attributes can be added to the module. They will show up in the
/// module View if they have a corresponding ColumnDescriptor.
///
/// To avoid an unnecessary proliferation of additional attributes with similar
/// semantics but different names
/// we recommend to re-use attributes from the 'recommended' list below first,
/// and only introduce new attributes if nothing appropriate could be found.
class Module {
  /// Address range covered by this module.
  final String? addressRange;

  /// Module created or modified.
  final String? dateTimeStamp;

  /// Unique identifier for the module.
  final Either2<int, String> id;

  /// True if the module is optimized.
  final bool? isOptimized;

  /// True if the module is considered 'user code' by a debugger that supports
  /// 'Just My Code'.
  final bool? isUserCode;

  /// A name of the module.
  final String name;

  /// optional but recommended attributes.
  /// always try to use these first before introducing additional attributes.
  ///
  /// Logical full path to the module. The exact definition is implementation
  /// defined, but usually this would be a full path to the on-disk file for the
  /// module.
  final String? path;

  /// Logical full path to the symbol file. The exact definition is
  /// implementation defined.
  final String? symbolFilePath;

  /// User understandable description of if symbols were found for the module
  /// (ex: 'Symbols Loaded', 'Symbols not found', etc.
  final String? symbolStatus;

  /// Version of Module.
  final String? version;

  static Module fromJson(Map<String, Object?> obj) => Module.fromMap(obj);

  Module({
    this.addressRange,
    this.dateTimeStamp,
    required this.id,
    this.isOptimized,
    this.isUserCode,
    required this.name,
    this.path,
    this.symbolFilePath,
    this.symbolStatus,
    this.version,
  });

  Module.fromMap(Map<String, Object?> obj)
      : addressRange = obj['addressRange'] as String?,
        dateTimeStamp = obj['dateTimeStamp'] as String?,
        id = obj['id'] is int
            ? Either2<int, String>.t1(obj['id'] as int)
            : Either2<int, String>.t2(obj['id'] as String),
        isOptimized = obj['isOptimized'] as bool?,
        isUserCode = obj['isUserCode'] as bool?,
        name = obj['name'] as String,
        path = obj['path'] as String?,
        symbolFilePath = obj['symbolFilePath'] as String?,
        symbolStatus = obj['symbolStatus'] as String?,
        version = obj['version'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['addressRange'] is! String?) {
      return false;
    }
    if (obj['dateTimeStamp'] is! String?) {
      return false;
    }
    if ((obj['id'] is! int && obj['id'] is! String)) {
      return false;
    }
    if (obj['isOptimized'] is! bool?) {
      return false;
    }
    if (obj['isUserCode'] is! bool?) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['path'] is! String?) {
      return false;
    }
    if (obj['symbolFilePath'] is! String?) {
      return false;
    }
    if (obj['symbolStatus'] is! String?) {
      return false;
    }
    if (obj['version'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (addressRange != null) 'addressRange': addressRange,
        if (dateTimeStamp != null) 'dateTimeStamp': dateTimeStamp,
        'id': id,
        if (isOptimized != null) 'isOptimized': isOptimized,
        if (isUserCode != null) 'isUserCode': isUserCode,
        'name': name,
        if (path != null) 'path': path,
        if (symbolFilePath != null) 'symbolFilePath': symbolFilePath,
        if (symbolStatus != null) 'symbolStatus': symbolStatus,
        if (version != null) 'version': version,
      };
}

/// Arguments for 'modules' request.
class ModulesArguments extends RequestArguments {
  /// The number of modules to return. If moduleCount is not specified or 0, all
  /// modules are returned.
  final int? moduleCount;

  /// The index of the first module to return; if omitted modules start at 0.
  final int? startModule;

  static ModulesArguments fromJson(Map<String, Object?> obj) =>
      ModulesArguments.fromMap(obj);

  ModulesArguments({
    this.moduleCount,
    this.startModule,
  });

  ModulesArguments.fromMap(Map<String, Object?> obj)
      : moduleCount = obj['moduleCount'] as int?,
        startModule = obj['startModule'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['moduleCount'] is! int?) {
      return false;
    }
    if (obj['startModule'] is! int?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (moduleCount != null) 'moduleCount': moduleCount,
        if (startModule != null) 'startModule': startModule,
      };
}

/// Response to 'modules' request.
class ModulesResponse extends Response {
  static ModulesResponse fromJson(Map<String, Object?> obj) =>
      ModulesResponse.fromMap(obj);

  ModulesResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ModulesResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// The ModulesViewDescriptor is the container for all declarative configuration
/// options of a ModuleView.
/// For now it only specifies the columns to be shown in the modules view.
class ModulesViewDescriptor {
  final List<ColumnDescriptor> columns;

  static ModulesViewDescriptor fromJson(Map<String, Object?> obj) =>
      ModulesViewDescriptor.fromMap(obj);

  ModulesViewDescriptor({
    required this.columns,
  });

  ModulesViewDescriptor.fromMap(Map<String, Object?> obj)
      : columns = (obj['columns'] as List)
            .map((item) =>
                ColumnDescriptor.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['columns'] is! List ||
        (obj['columns'].any((item) => !ColumnDescriptor.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'columns': columns,
      };
}

/// Arguments for 'next' request.
class NextArguments extends RequestArguments {
  /// Optional granularity to step. If no granularity is specified, a
  /// granularity of 'statement' is assumed.
  final SteppingGranularity? granularity;

  /// Execute 'next' for this thread.
  final int threadId;

  static NextArguments fromJson(Map<String, Object?> obj) =>
      NextArguments.fromMap(obj);

  NextArguments({
    this.granularity,
    required this.threadId,
  });

  NextArguments.fromMap(Map<String, Object?> obj)
      : granularity = obj['granularity'] as SteppingGranularity?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['granularity'] is! SteppingGranularity?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (granularity != null) 'granularity': granularity,
        'threadId': threadId,
      };
}

/// Response to 'next' request. This is just an acknowledgement, so no body
/// field is required.
class NextResponse extends Response {
  static NextResponse fromJson(Map<String, Object?> obj) =>
      NextResponse.fromMap(obj);

  NextResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  NextResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'pause' request.
class PauseArguments extends RequestArguments {
  /// Pause execution for this thread.
  final int threadId;

  static PauseArguments fromJson(Map<String, Object?> obj) =>
      PauseArguments.fromMap(obj);

  PauseArguments({
    required this.threadId,
  });

  PauseArguments.fromMap(Map<String, Object?> obj)
      : threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'threadId': threadId,
      };
}

/// Response to 'pause' request. This is just an acknowledgement, so no body
/// field is required.
class PauseResponse extends Response {
  static PauseResponse fromJson(Map<String, Object?> obj) =>
      PauseResponse.fromMap(obj);

  PauseResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  PauseResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Base class of requests, responses, and events.
class ProtocolMessage {
  /// Sequence number (also known as message ID). For protocol messages of type
  /// 'request' this ID can be used to cancel the request.
  final int seq;

  /// Message type.
  final String type;

  static ProtocolMessage fromJson(Map<String, Object?> obj) =>
      ProtocolMessage.fromMap(obj);

  ProtocolMessage({
    required this.seq,
    required this.type,
  });

  ProtocolMessage.fromMap(Map<String, Object?> obj)
      : seq = obj['seq'] as int,
        type = obj['type'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['seq'] is! int) {
      return false;
    }
    if (obj['type'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'seq': seq,
        'type': type,
      };
}

/// Arguments for 'readMemory' request.
class ReadMemoryArguments extends RequestArguments {
  /// Number of bytes to read at the specified location and offset.
  final int count;

  /// Memory reference to the base location from which data should be read.
  final String memoryReference;

  /// Optional offset (in bytes) to be applied to the reference location before
  /// reading data. Can be negative.
  final int? offset;

  static ReadMemoryArguments fromJson(Map<String, Object?> obj) =>
      ReadMemoryArguments.fromMap(obj);

  ReadMemoryArguments({
    required this.count,
    required this.memoryReference,
    this.offset,
  });

  ReadMemoryArguments.fromMap(Map<String, Object?> obj)
      : count = obj['count'] as int,
        memoryReference = obj['memoryReference'] as String,
        offset = obj['offset'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['count'] is! int) {
      return false;
    }
    if (obj['memoryReference'] is! String) {
      return false;
    }
    if (obj['offset'] is! int?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'count': count,
        'memoryReference': memoryReference,
        if (offset != null) 'offset': offset,
      };
}

/// Response to 'readMemory' request.
class ReadMemoryResponse extends Response {
  static ReadMemoryResponse fromJson(Map<String, Object?> obj) =>
      ReadMemoryResponse.fromMap(obj);

  ReadMemoryResponse({
    Map<String, Object?>? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ReadMemoryResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>?) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A client or debug adapter initiated request.
class Request extends ProtocolMessage {
  /// Object containing arguments for the command.
  final Object? arguments;

  /// The command to execute.
  final String command;

  static Request fromJson(Map<String, Object?> obj) => Request.fromMap(obj);

  Request({
    this.arguments,
    required this.command,
    required int seq,
  }) : super(
          seq: seq,
          type: 'request',
        );

  Request.fromMap(Map<String, Object?> obj)
      : arguments = obj['arguments'],
        command = obj['command'] as String,
        super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['command'] is! String) {
      return false;
    }
    if (obj['type'] is! String) {
      return false;
    }
    return ProtocolMessage.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
        if (arguments != null) 'arguments': arguments,
        'command': command,
      };
}

/// Response for a request.
class Response extends ProtocolMessage {
  /// Contains request result if success is true and optional error details if
  /// success is false.
  final Object? body;

  /// The command requested.
  final String command;

  /// Contains the raw error in short form if 'success' is false.
  /// This raw error might be interpreted by the frontend and is not shown in
  /// the UI.
  /// Some predefined values exist.
  final String? message;

  /// Sequence number of the corresponding request.
  final int requestSeq;

  /// Outcome of the request.
  /// If true, the request was successful and the 'body' attribute may contain
  /// the result of the request.
  /// If the value is false, the attribute 'message' contains the error in short
  /// form and the 'body' may contain additional information (see
  /// 'ErrorResponse.body.error').
  final bool success;

  static Response fromJson(Map<String, Object?> obj) => Response.fromMap(obj);

  Response({
    this.body,
    required this.command,
    this.message,
    required this.requestSeq,
    required this.success,
    required int seq,
  }) : super(
          seq: seq,
          type: 'response',
        );

  Response.fromMap(Map<String, Object?> obj)
      : body = obj['body'],
        command = obj['command'] as String,
        message = obj['message'] as String?,
        requestSeq = obj['request_seq'] as int,
        success = obj['success'] as bool,
        super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['command'] is! String) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['request_seq'] is! int) {
      return false;
    }
    if (obj['success'] is! bool) {
      return false;
    }
    if (obj['type'] is! String) {
      return false;
    }
    return ProtocolMessage.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
        if (body != null) 'body': body,
        'command': command,
        if (message != null) 'message': message,
        'request_seq': requestSeq,
        'success': success,
      };
}

/// Arguments for 'restart' request.
class RestartArguments extends RequestArguments {
  /// The latest version of the 'launch' or 'attach' configuration.
  final Either2<LaunchRequestArguments, AttachRequestArguments>? arguments;

  static RestartArguments fromJson(Map<String, Object?> obj) =>
      RestartArguments.fromMap(obj);

  RestartArguments({
    this.arguments,
  });

  RestartArguments.fromMap(Map<String, Object?> obj)
      : arguments = LaunchRequestArguments.canParse(obj['arguments'])
            ? Either2<LaunchRequestArguments, AttachRequestArguments>.t1(
                LaunchRequestArguments.fromJson(
                    obj['arguments'] as Map<String, Object?>))
            : AttachRequestArguments.canParse(obj['arguments'])
                ? Either2<LaunchRequestArguments, AttachRequestArguments>.t2(
                    AttachRequestArguments.fromJson(
                        obj['arguments'] as Map<String, Object?>))
                : null;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((!LaunchRequestArguments.canParse(obj['arguments']) &&
        !AttachRequestArguments.canParse(obj['arguments']) &&
        obj['arguments'] != null)) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (arguments != null) 'arguments': arguments,
      };
}

/// Arguments for 'restartFrame' request.
class RestartFrameArguments extends RequestArguments {
  /// Restart this stackframe.
  final int frameId;

  static RestartFrameArguments fromJson(Map<String, Object?> obj) =>
      RestartFrameArguments.fromMap(obj);

  RestartFrameArguments({
    required this.frameId,
  });

  RestartFrameArguments.fromMap(Map<String, Object?> obj)
      : frameId = obj['frameId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['frameId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'frameId': frameId,
      };
}

/// Response to 'restartFrame' request. This is just an acknowledgement, so no
/// body field is required.
class RestartFrameResponse extends Response {
  static RestartFrameResponse fromJson(Map<String, Object?> obj) =>
      RestartFrameResponse.fromMap(obj);

  RestartFrameResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  RestartFrameResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Response to 'restart' request. This is just an acknowledgement, so no body
/// field is required.
class RestartResponse extends Response {
  static RestartResponse fromJson(Map<String, Object?> obj) =>
      RestartResponse.fromMap(obj);

  RestartResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  RestartResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'reverseContinue' request.
class ReverseContinueArguments extends RequestArguments {
  /// Execute 'reverseContinue' for this thread.
  final int threadId;

  static ReverseContinueArguments fromJson(Map<String, Object?> obj) =>
      ReverseContinueArguments.fromMap(obj);

  ReverseContinueArguments({
    required this.threadId,
  });

  ReverseContinueArguments.fromMap(Map<String, Object?> obj)
      : threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'threadId': threadId,
      };
}

/// Response to 'reverseContinue' request. This is just an acknowledgement, so
/// no body field is required.
class ReverseContinueResponse extends Response {
  static ReverseContinueResponse fromJson(Map<String, Object?> obj) =>
      ReverseContinueResponse.fromMap(obj);

  ReverseContinueResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ReverseContinueResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'runInTerminal' request.
class RunInTerminalRequestArguments extends RequestArguments {
  /// List of arguments. The first argument is the command to run.
  final List<String> args;

  /// Working directory for the command. For non-empty, valid paths this
  /// typically results in execution of a change directory command.
  final String cwd;

  /// Environment key-value pairs that are added to or removed from the default
  /// environment.
  final Map<String, Object?>? env;

  /// What kind of terminal to launch.
  final String? kind;

  /// Optional title of the terminal.
  final String? title;

  static RunInTerminalRequestArguments fromJson(Map<String, Object?> obj) =>
      RunInTerminalRequestArguments.fromMap(obj);

  RunInTerminalRequestArguments({
    required this.args,
    required this.cwd,
    this.env,
    this.kind,
    this.title,
  });

  RunInTerminalRequestArguments.fromMap(Map<String, Object?> obj)
      : args = (obj['args'] as List).map((item) => item as String).toList(),
        cwd = obj['cwd'] as String,
        env = obj['env'] as Map<String, Object?>?,
        kind = obj['kind'] as String?,
        title = obj['title'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['args'] is! List ||
        (obj['args'].any((item) => item is! String)))) {
      return false;
    }
    if (obj['cwd'] is! String) {
      return false;
    }
    if (obj['env'] is! Map<String, Object?>?) {
      return false;
    }
    if (obj['kind'] is! String?) {
      return false;
    }
    if (obj['title'] is! String?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'args': args,
        'cwd': cwd,
        if (env != null) 'env': env,
        if (kind != null) 'kind': kind,
        if (title != null) 'title': title,
      };
}

/// Response to 'runInTerminal' request.
class RunInTerminalResponse extends Response {
  static RunInTerminalResponse fromJson(Map<String, Object?> obj) =>
      RunInTerminalResponse.fromMap(obj);

  RunInTerminalResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  RunInTerminalResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A Scope is a named container for variables. Optionally a scope can map to a
/// source or a range within a source.
class Scope {
  /// Optional start column of the range covered by this scope.
  final int? column;

  /// Optional end column of the range covered by this scope.
  final int? endColumn;

  /// Optional end line of the range covered by this scope.
  final int? endLine;

  /// If true, the number of variables in this scope is large or expensive to
  /// retrieve.
  final bool expensive;

  /// The number of indexed variables in this scope.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  final int? indexedVariables;

  /// Optional start line of the range covered by this scope.
  final int? line;

  /// Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This
  /// string is shown in the UI as is and can be translated.
  final String name;

  /// The number of named variables in this scope.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  final int? namedVariables;

  /// An optional hint for how to present this scope in the UI. If this
  /// attribute is missing, the scope is shown with a generic UI.
  final String? presentationHint;

  /// Optional source for this scope.
  final Source? source;

  /// The variables of this scope can be retrieved by passing the value of
  /// variablesReference to the VariablesRequest.
  final int variablesReference;

  static Scope fromJson(Map<String, Object?> obj) => Scope.fromMap(obj);

  Scope({
    this.column,
    this.endColumn,
    this.endLine,
    required this.expensive,
    this.indexedVariables,
    this.line,
    required this.name,
    this.namedVariables,
    this.presentationHint,
    this.source,
    required this.variablesReference,
  });

  Scope.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        expensive = obj['expensive'] as bool,
        indexedVariables = obj['indexedVariables'] as int?,
        line = obj['line'] as int?,
        name = obj['name'] as String,
        namedVariables = obj['namedVariables'] as int?,
        presentationHint = obj['presentationHint'] as String?,
        source = obj['source'] == null
            ? null
            : Source.fromJson(obj['source'] as Map<String, Object?>),
        variablesReference = obj['variablesReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['expensive'] is! bool) {
      return false;
    }
    if (obj['indexedVariables'] is! int?) {
      return false;
    }
    if (obj['line'] is! int?) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['namedVariables'] is! int?) {
      return false;
    }
    if (obj['presentationHint'] is! String?) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    if (obj['variablesReference'] is! int) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'expensive': expensive,
        if (indexedVariables != null) 'indexedVariables': indexedVariables,
        if (line != null) 'line': line,
        'name': name,
        if (namedVariables != null) 'namedVariables': namedVariables,
        if (presentationHint != null) 'presentationHint': presentationHint,
        if (source != null) 'source': source,
        'variablesReference': variablesReference,
      };
}

/// Arguments for 'scopes' request.
class ScopesArguments extends RequestArguments {
  /// Retrieve the scopes for this stackframe.
  final int frameId;

  static ScopesArguments fromJson(Map<String, Object?> obj) =>
      ScopesArguments.fromMap(obj);

  ScopesArguments({
    required this.frameId,
  });

  ScopesArguments.fromMap(Map<String, Object?> obj)
      : frameId = obj['frameId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['frameId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'frameId': frameId,
      };
}

/// Response to 'scopes' request.
class ScopesResponse extends Response {
  static ScopesResponse fromJson(Map<String, Object?> obj) =>
      ScopesResponse.fromMap(obj);

  ScopesResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ScopesResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setBreakpoints' request.
class SetBreakpointsArguments extends RequestArguments {
  /// The code locations of the breakpoints.
  final List<SourceBreakpoint>? breakpoints;

  /// Deprecated: The code locations of the breakpoints.
  final List<int>? lines;

  /// The source location of the breakpoints; either 'source.path' or
  /// 'source.reference' must be specified.
  final Source source;

  /// A value of true indicates that the underlying source has been modified
  /// which results in new breakpoint locations.
  final bool? sourceModified;

  static SetBreakpointsArguments fromJson(Map<String, Object?> obj) =>
      SetBreakpointsArguments.fromMap(obj);

  SetBreakpointsArguments({
    this.breakpoints,
    this.lines,
    required this.source,
    this.sourceModified,
  });

  SetBreakpointsArguments.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List?)
            ?.map((item) =>
                SourceBreakpoint.fromJson(item as Map<String, Object?>))
            .toList(),
        lines = (obj['lines'] as List?)?.map((item) => item as int).toList(),
        source = Source.fromJson(obj['source'] as Map<String, Object?>),
        sourceModified = obj['sourceModified'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !SourceBreakpoint.canParse(item))))) {
      return false;
    }
    if ((obj['lines'] is! List || (obj['lines'].any((item) => item is! int)))) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    if (obj['sourceModified'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (breakpoints != null) 'breakpoints': breakpoints,
        if (lines != null) 'lines': lines,
        'source': source,
        if (sourceModified != null) 'sourceModified': sourceModified,
      };
}

/// Response to 'setBreakpoints' request.
/// Returned is information about each breakpoint created by this request.
/// This includes the actual code location and whether the breakpoint could be
/// verified.
/// The breakpoints returned are in the same order as the elements of the
/// 'breakpoints'
/// (or the deprecated 'lines') array in the arguments.
class SetBreakpointsResponse extends Response {
  static SetBreakpointsResponse fromJson(Map<String, Object?> obj) =>
      SetBreakpointsResponse.fromMap(obj);

  SetBreakpointsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetBreakpointsResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setDataBreakpoints' request.
class SetDataBreakpointsArguments extends RequestArguments {
  /// The contents of this array replaces all existing data breakpoints. An
  /// empty array clears all data breakpoints.
  final List<DataBreakpoint> breakpoints;

  static SetDataBreakpointsArguments fromJson(Map<String, Object?> obj) =>
      SetDataBreakpointsArguments.fromMap(obj);

  SetDataBreakpointsArguments({
    required this.breakpoints,
  });

  SetDataBreakpointsArguments.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map(
                (item) => DataBreakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !DataBreakpoint.canParse(item))))) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

/// Response to 'setDataBreakpoints' request.
/// Returned is information about each breakpoint created by this request.
class SetDataBreakpointsResponse extends Response {
  static SetDataBreakpointsResponse fromJson(Map<String, Object?> obj) =>
      SetDataBreakpointsResponse.fromMap(obj);

  SetDataBreakpointsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetDataBreakpointsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setExceptionBreakpoints' request.
class SetExceptionBreakpointsArguments extends RequestArguments {
  /// Configuration options for selected exceptions.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsExceptionOptions' is true.
  final List<ExceptionOptions>? exceptionOptions;

  /// Set of exception filters and their options. The set of all possible
  /// exception filters is defined by the 'exceptionBreakpointFilters'
  /// capability. This attribute is only honored by a debug adapter if the
  /// capability 'supportsExceptionFilterOptions' is true. The 'filter' and
  /// 'filterOptions' sets are additive.
  final List<ExceptionFilterOptions>? filterOptions;

  /// Set of exception filters specified by their ID. The set of all possible
  /// exception filters is defined by the 'exceptionBreakpointFilters'
  /// capability. The 'filter' and 'filterOptions' sets are additive.
  final List<String> filters;

  static SetExceptionBreakpointsArguments fromJson(Map<String, Object?> obj) =>
      SetExceptionBreakpointsArguments.fromMap(obj);

  SetExceptionBreakpointsArguments({
    this.exceptionOptions,
    this.filterOptions,
    required this.filters,
  });

  SetExceptionBreakpointsArguments.fromMap(Map<String, Object?> obj)
      : exceptionOptions = (obj['exceptionOptions'] as List?)
            ?.map((item) =>
                ExceptionOptions.fromJson(item as Map<String, Object?>))
            .toList(),
        filterOptions = (obj['filterOptions'] as List?)
            ?.map((item) =>
                ExceptionFilterOptions.fromJson(item as Map<String, Object?>))
            .toList(),
        filters =
            (obj['filters'] as List).map((item) => item as String).toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['exceptionOptions'] is! List ||
        (obj['exceptionOptions']
            .any((item) => !ExceptionOptions.canParse(item))))) {
      return false;
    }
    if ((obj['filterOptions'] is! List ||
        (obj['filterOptions']
            .any((item) => !ExceptionFilterOptions.canParse(item))))) {
      return false;
    }
    if ((obj['filters'] is! List ||
        (obj['filters'].any((item) => item is! String)))) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (exceptionOptions != null) 'exceptionOptions': exceptionOptions,
        if (filterOptions != null) 'filterOptions': filterOptions,
        'filters': filters,
      };
}

/// Response to 'setExceptionBreakpoints' request.
/// The response contains an array of Breakpoint objects with information about
/// each exception breakpoint or filter. The Breakpoint objects are in the same
/// order as the elements of the 'filters', 'filterOptions', 'exceptionOptions'
/// arrays given as arguments. If both 'filters' and 'filterOptions' are given,
/// the returned array must start with 'filters' information first, followed by
/// 'filterOptions' information.
/// The mandatory 'verified' property of a Breakpoint object signals whether the
/// exception breakpoint or filter could be successfully created and whether the
/// optional condition or hit count expressions are valid. In case of an error
/// the 'message' property explains the problem. An optional 'id' property can
/// be used to introduce a unique ID for the exception breakpoint or filter so
/// that it can be updated subsequently by sending breakpoint events.
/// For backward compatibility both the 'breakpoints' array and the enclosing
/// 'body' are optional. If these elements are missing a client will not be able
/// to show problems for individual exception breakpoints or filters.
class SetExceptionBreakpointsResponse extends Response {
  static SetExceptionBreakpointsResponse fromJson(Map<String, Object?> obj) =>
      SetExceptionBreakpointsResponse.fromMap(obj);

  SetExceptionBreakpointsResponse({
    Map<String, Object?>? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetExceptionBreakpointsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>?) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setExpression' request.
class SetExpressionArguments extends RequestArguments {
  /// The l-value expression to assign to.
  final String expression;

  /// Specifies how the resulting value should be formatted.
  final ValueFormat? format;

  /// Evaluate the expressions in the scope of this stack frame. If not
  /// specified, the expressions are evaluated in the global scope.
  final int? frameId;

  /// The value expression to assign to the l-value expression.
  final String value;

  static SetExpressionArguments fromJson(Map<String, Object?> obj) =>
      SetExpressionArguments.fromMap(obj);

  SetExpressionArguments({
    required this.expression,
    this.format,
    this.frameId,
    required this.value,
  });

  SetExpressionArguments.fromMap(Map<String, Object?> obj)
      : expression = obj['expression'] as String,
        format = obj['format'] == null
            ? null
            : ValueFormat.fromJson(obj['format'] as Map<String, Object?>),
        frameId = obj['frameId'] as int?,
        value = obj['value'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['expression'] is! String) {
      return false;
    }
    if (!ValueFormat.canParse(obj['format'])) {
      return false;
    }
    if (obj['frameId'] is! int?) {
      return false;
    }
    if (obj['value'] is! String) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'expression': expression,
        if (format != null) 'format': format,
        if (frameId != null) 'frameId': frameId,
        'value': value,
      };
}

/// Response to 'setExpression' request.
class SetExpressionResponse extends Response {
  static SetExpressionResponse fromJson(Map<String, Object?> obj) =>
      SetExpressionResponse.fromMap(obj);

  SetExpressionResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetExpressionResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setFunctionBreakpoints' request.
class SetFunctionBreakpointsArguments extends RequestArguments {
  /// The function names of the breakpoints.
  final List<FunctionBreakpoint> breakpoints;

  static SetFunctionBreakpointsArguments fromJson(Map<String, Object?> obj) =>
      SetFunctionBreakpointsArguments.fromMap(obj);

  SetFunctionBreakpointsArguments({
    required this.breakpoints,
  });

  SetFunctionBreakpointsArguments.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) =>
                FunctionBreakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints']
            .any((item) => !FunctionBreakpoint.canParse(item))))) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

/// Response to 'setFunctionBreakpoints' request.
/// Returned is information about each breakpoint created by this request.
class SetFunctionBreakpointsResponse extends Response {
  static SetFunctionBreakpointsResponse fromJson(Map<String, Object?> obj) =>
      SetFunctionBreakpointsResponse.fromMap(obj);

  SetFunctionBreakpointsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetFunctionBreakpointsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setInstructionBreakpoints' request
class SetInstructionBreakpointsArguments extends RequestArguments {
  /// The instruction references of the breakpoints
  final List<InstructionBreakpoint> breakpoints;

  static SetInstructionBreakpointsArguments fromJson(
          Map<String, Object?> obj) =>
      SetInstructionBreakpointsArguments.fromMap(obj);

  SetInstructionBreakpointsArguments({
    required this.breakpoints,
  });

  SetInstructionBreakpointsArguments.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) =>
                InstructionBreakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints']
            .any((item) => !InstructionBreakpoint.canParse(item))))) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

/// Response to 'setInstructionBreakpoints' request
class SetInstructionBreakpointsResponse extends Response {
  static SetInstructionBreakpointsResponse fromJson(Map<String, Object?> obj) =>
      SetInstructionBreakpointsResponse.fromMap(obj);

  SetInstructionBreakpointsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetInstructionBreakpointsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'setVariable' request.
class SetVariableArguments extends RequestArguments {
  /// Specifies details on how to format the response value.
  final ValueFormat? format;

  /// The name of the variable in the container.
  final String name;

  /// The value of the variable.
  final String value;

  /// The reference of the variable container.
  final int variablesReference;

  static SetVariableArguments fromJson(Map<String, Object?> obj) =>
      SetVariableArguments.fromMap(obj);

  SetVariableArguments({
    this.format,
    required this.name,
    required this.value,
    required this.variablesReference,
  });

  SetVariableArguments.fromMap(Map<String, Object?> obj)
      : format = obj['format'] == null
            ? null
            : ValueFormat.fromJson(obj['format'] as Map<String, Object?>),
        name = obj['name'] as String,
        value = obj['value'] as String,
        variablesReference = obj['variablesReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!ValueFormat.canParse(obj['format'])) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['value'] is! String) {
      return false;
    }
    if (obj['variablesReference'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (format != null) 'format': format,
        'name': name,
        'value': value,
        'variablesReference': variablesReference,
      };
}

/// Response to 'setVariable' request.
class SetVariableResponse extends Response {
  static SetVariableResponse fromJson(Map<String, Object?> obj) =>
      SetVariableResponse.fromMap(obj);

  SetVariableResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SetVariableResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A Source is a descriptor for source code.
/// It is returned from the debug adapter as part of a StackFrame and it is used
/// by clients when specifying breakpoints.
class Source {
  /// Optional data that a debug adapter might want to loop through the client.
  /// The client should leave the data intact and persist it across sessions.
  /// The client should not interpret the data.
  final Object? adapterData;

  /// The checksums associated with this file.
  final List<Checksum>? checksums;

  /// The short name of the source. Every source returned from the debug adapter
  /// has a name.
  /// When sending a source to the debug adapter this name is optional.
  final String? name;

  /// The (optional) origin of this source: possible values 'internal module',
  /// 'inlined content from source map', etc.
  final String? origin;

  /// The path of the source to be shown in the UI.
  /// It is only used to locate and load the content of the source if no
  /// sourceReference is specified (or its value is 0).
  final String? path;

  /// An optional hint for how to present the source in the UI.
  /// A value of 'deemphasize' can be used to indicate that the source is not
  /// available or that it is skipped on stepping.
  final String? presentationHint;

  /// If sourceReference > 0 the contents of the source must be retrieved
  /// through the SourceRequest (even if a path is specified).
  /// A sourceReference is only valid for a session, so it must not be used to
  /// persist a source.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? sourceReference;

  /// An optional list of sources that are related to this source. These may be
  /// the source that generated this source.
  final List<Source>? sources;

  static Source fromJson(Map<String, Object?> obj) => Source.fromMap(obj);

  Source({
    this.adapterData,
    this.checksums,
    this.name,
    this.origin,
    this.path,
    this.presentationHint,
    this.sourceReference,
    this.sources,
  });

  Source.fromMap(Map<String, Object?> obj)
      : adapterData = obj['adapterData'],
        checksums = (obj['checksums'] as List?)
            ?.map((item) => Checksum.fromJson(item as Map<String, Object?>))
            .toList(),
        name = obj['name'] as String?,
        origin = obj['origin'] as String?,
        path = obj['path'] as String?,
        presentationHint = obj['presentationHint'] as String?,
        sourceReference = obj['sourceReference'] as int?,
        sources = (obj['sources'] as List?)
            ?.map((item) => Source.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['checksums'] is! List ||
        (obj['checksums'].any((item) => !Checksum.canParse(item))))) {
      return false;
    }
    if (obj['name'] is! String?) {
      return false;
    }
    if (obj['origin'] is! String?) {
      return false;
    }
    if (obj['path'] is! String?) {
      return false;
    }
    if (obj['presentationHint'] is! String?) {
      return false;
    }
    if (obj['sourceReference'] is! int?) {
      return false;
    }
    if ((obj['sources'] is! List ||
        (obj['sources'].any((item) => !Source.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (adapterData != null) 'adapterData': adapterData,
        if (checksums != null) 'checksums': checksums,
        if (name != null) 'name': name,
        if (origin != null) 'origin': origin,
        if (path != null) 'path': path,
        if (presentationHint != null) 'presentationHint': presentationHint,
        if (sourceReference != null) 'sourceReference': sourceReference,
        if (sources != null) 'sources': sources,
      };
}

/// Arguments for 'source' request.
class SourceArguments extends RequestArguments {
  /// Specifies the source content to load. Either source.path or
  /// source.sourceReference must be specified.
  final Source? source;

  /// The reference to the source. This is the same as source.sourceReference.
  /// This is provided for backward compatibility since old backends do not
  /// understand the 'source' attribute.
  final int sourceReference;

  static SourceArguments fromJson(Map<String, Object?> obj) =>
      SourceArguments.fromMap(obj);

  SourceArguments({
    this.source,
    required this.sourceReference,
  });

  SourceArguments.fromMap(Map<String, Object?> obj)
      : source = obj['source'] == null
            ? null
            : Source.fromJson(obj['source'] as Map<String, Object?>),
        sourceReference = obj['sourceReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    if (obj['sourceReference'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (source != null) 'source': source,
        'sourceReference': sourceReference,
      };
}

/// Properties of a breakpoint or logpoint passed to the setBreakpoints request.
class SourceBreakpoint {
  /// An optional source column of the breakpoint.
  final int? column;

  /// An optional expression for conditional breakpoints.
  /// It is only honored by a debug adapter if the capability
  /// 'supportsConditionalBreakpoints' is true.
  final String? condition;

  /// An optional expression that controls how many hits of the breakpoint are
  /// ignored.
  /// The backend is expected to interpret the expression as needed.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsHitConditionalBreakpoints' is true.
  final String? hitCondition;

  /// The source line of the breakpoint or logpoint.
  final int line;

  /// If this attribute exists and is non-empty, the backend must not 'break'
  /// (stop)
  /// but log the message instead. Expressions within {} are interpolated.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsLogPoints' is true.
  final String? logMessage;

  static SourceBreakpoint fromJson(Map<String, Object?> obj) =>
      SourceBreakpoint.fromMap(obj);

  SourceBreakpoint({
    this.column,
    this.condition,
    this.hitCondition,
    required this.line,
    this.logMessage,
  });

  SourceBreakpoint.fromMap(Map<String, Object?> obj)
      : column = obj['column'] as int?,
        condition = obj['condition'] as String?,
        hitCondition = obj['hitCondition'] as String?,
        line = obj['line'] as int,
        logMessage = obj['logMessage'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['condition'] is! String?) {
      return false;
    }
    if (obj['hitCondition'] is! String?) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    if (obj['logMessage'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (column != null) 'column': column,
        if (condition != null) 'condition': condition,
        if (hitCondition != null) 'hitCondition': hitCondition,
        'line': line,
        if (logMessage != null) 'logMessage': logMessage,
      };
}

/// Response to 'source' request.
class SourceResponse extends Response {
  static SourceResponse fromJson(Map<String, Object?> obj) =>
      SourceResponse.fromMap(obj);

  SourceResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  SourceResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A Stackframe contains the source location.
class StackFrame {
  /// Indicates whether this frame can be restarted with the 'restart' request.
  /// Clients should only use this if the debug adapter supports the 'restart'
  /// request (capability 'supportsRestartRequest' is true).
  final bool? canRestart;

  /// The column within the line. If source is null or doesn't exist, column is
  /// 0 and must be ignored.
  final int column;

  /// An optional end column of the range covered by the stack frame.
  final int? endColumn;

  /// An optional end line of the range covered by the stack frame.
  final int? endLine;

  /// An identifier for the stack frame. It must be unique across all threads.
  /// This id can be used to retrieve the scopes of the frame with the
  /// 'scopesRequest' or to restart the execution of a stackframe.
  final int id;

  /// Optional memory reference for the current instruction pointer in this
  /// frame.
  final String? instructionPointerReference;

  /// The line within the file of the frame. If source is null or doesn't exist,
  /// line is 0 and must be ignored.
  final int line;

  /// The module associated with this frame, if any.
  final Either2<int, String>? moduleId;

  /// The name of the stack frame, typically a method name.
  final String name;

  /// An optional hint for how to present this frame in the UI.
  /// A value of 'label' can be used to indicate that the frame is an artificial
  /// frame that is used as a visual label or separator. A value of 'subtle' can
  /// be used to change the appearance of a frame in a 'subtle' way.
  final String? presentationHint;

  /// The optional source of the frame.
  final Source? source;

  static StackFrame fromJson(Map<String, Object?> obj) =>
      StackFrame.fromMap(obj);

  StackFrame({
    this.canRestart,
    required this.column,
    this.endColumn,
    this.endLine,
    required this.id,
    this.instructionPointerReference,
    required this.line,
    this.moduleId,
    required this.name,
    this.presentationHint,
    this.source,
  });

  StackFrame.fromMap(Map<String, Object?> obj)
      : canRestart = obj['canRestart'] as bool?,
        column = obj['column'] as int,
        endColumn = obj['endColumn'] as int?,
        endLine = obj['endLine'] as int?,
        id = obj['id'] as int,
        instructionPointerReference =
            obj['instructionPointerReference'] as String?,
        line = obj['line'] as int,
        moduleId = obj['moduleId'] is int
            ? Either2<int, String>.t1(obj['moduleId'] as int)
            : obj['moduleId'] is String
                ? Either2<int, String>.t2(obj['moduleId'] as String)
                : null,
        name = obj['name'] as String,
        presentationHint = obj['presentationHint'] as String?,
        source = obj['source'] == null
            ? null
            : Source.fromJson(obj['source'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['canRestart'] is! bool?) {
      return false;
    }
    if (obj['column'] is! int) {
      return false;
    }
    if (obj['endColumn'] is! int?) {
      return false;
    }
    if (obj['endLine'] is! int?) {
      return false;
    }
    if (obj['id'] is! int) {
      return false;
    }
    if (obj['instructionPointerReference'] is! String?) {
      return false;
    }
    if (obj['line'] is! int) {
      return false;
    }
    if ((obj['moduleId'] is! int &&
        obj['moduleId'] is! String &&
        obj['moduleId'] != null)) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['presentationHint'] is! String?) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (canRestart != null) 'canRestart': canRestart,
        'column': column,
        if (endColumn != null) 'endColumn': endColumn,
        if (endLine != null) 'endLine': endLine,
        'id': id,
        if (instructionPointerReference != null)
          'instructionPointerReference': instructionPointerReference,
        'line': line,
        if (moduleId != null) 'moduleId': moduleId,
        'name': name,
        if (presentationHint != null) 'presentationHint': presentationHint,
        if (source != null) 'source': source,
      };
}

/// Provides formatting information for a stack frame.
class StackFrameFormat extends ValueFormat {
  /// Includes all stack frames, including those the debug adapter might
  /// otherwise hide.
  final bool? includeAll;

  /// Displays the line number of the stack frame.
  final bool? line;

  /// Displays the module of the stack frame.
  final bool? module;

  /// Displays the names of parameters for the stack frame.
  final bool? parameterNames;

  /// Displays the types of parameters for the stack frame.
  final bool? parameterTypes;

  /// Displays the values of parameters for the stack frame.
  final bool? parameterValues;

  /// Displays parameters for the stack frame.
  final bool? parameters;

  static StackFrameFormat fromJson(Map<String, Object?> obj) =>
      StackFrameFormat.fromMap(obj);

  StackFrameFormat({
    this.includeAll,
    this.line,
    this.module,
    this.parameterNames,
    this.parameterTypes,
    this.parameterValues,
    this.parameters,
    bool? hex,
  }) : super(
          hex: hex,
        );

  StackFrameFormat.fromMap(Map<String, Object?> obj)
      : includeAll = obj['includeAll'] as bool?,
        line = obj['line'] as bool?,
        module = obj['module'] as bool?,
        parameterNames = obj['parameterNames'] as bool?,
        parameterTypes = obj['parameterTypes'] as bool?,
        parameterValues = obj['parameterValues'] as bool?,
        parameters = obj['parameters'] as bool?,
        super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['includeAll'] is! bool?) {
      return false;
    }
    if (obj['line'] is! bool?) {
      return false;
    }
    if (obj['module'] is! bool?) {
      return false;
    }
    if (obj['parameterNames'] is! bool?) {
      return false;
    }
    if (obj['parameterTypes'] is! bool?) {
      return false;
    }
    if (obj['parameterValues'] is! bool?) {
      return false;
    }
    if (obj['parameters'] is! bool?) {
      return false;
    }
    return ValueFormat.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
        if (includeAll != null) 'includeAll': includeAll,
        if (line != null) 'line': line,
        if (module != null) 'module': module,
        if (parameterNames != null) 'parameterNames': parameterNames,
        if (parameterTypes != null) 'parameterTypes': parameterTypes,
        if (parameterValues != null) 'parameterValues': parameterValues,
        if (parameters != null) 'parameters': parameters,
      };
}

/// Arguments for 'stackTrace' request.
class StackTraceArguments extends RequestArguments {
  /// Specifies details on how to format the stack frames.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsValueFormattingOptions' is true.
  final StackFrameFormat? format;

  /// The maximum number of frames to return. If levels is not specified or 0,
  /// all frames are returned.
  final int? levels;

  /// The index of the first frame to return; if omitted frames start at 0.
  final int? startFrame;

  /// Retrieve the stacktrace for this thread.
  final int threadId;

  static StackTraceArguments fromJson(Map<String, Object?> obj) =>
      StackTraceArguments.fromMap(obj);

  StackTraceArguments({
    this.format,
    this.levels,
    this.startFrame,
    required this.threadId,
  });

  StackTraceArguments.fromMap(Map<String, Object?> obj)
      : format = obj['format'] == null
            ? null
            : StackFrameFormat.fromJson(obj['format'] as Map<String, Object?>),
        levels = obj['levels'] as int?,
        startFrame = obj['startFrame'] as int?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!StackFrameFormat.canParse(obj['format'])) {
      return false;
    }
    if (obj['levels'] is! int?) {
      return false;
    }
    if (obj['startFrame'] is! int?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (format != null) 'format': format,
        if (levels != null) 'levels': levels,
        if (startFrame != null) 'startFrame': startFrame,
        'threadId': threadId,
      };
}

/// Response to 'stackTrace' request.
class StackTraceResponse extends Response {
  static StackTraceResponse fromJson(Map<String, Object?> obj) =>
      StackTraceResponse.fromMap(obj);

  StackTraceResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  StackTraceResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'stepBack' request.
class StepBackArguments extends RequestArguments {
  /// Optional granularity to step. If no granularity is specified, a
  /// granularity of 'statement' is assumed.
  final SteppingGranularity? granularity;

  /// Execute 'stepBack' for this thread.
  final int threadId;

  static StepBackArguments fromJson(Map<String, Object?> obj) =>
      StepBackArguments.fromMap(obj);

  StepBackArguments({
    this.granularity,
    required this.threadId,
  });

  StepBackArguments.fromMap(Map<String, Object?> obj)
      : granularity = obj['granularity'] as SteppingGranularity?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['granularity'] is! SteppingGranularity?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (granularity != null) 'granularity': granularity,
        'threadId': threadId,
      };
}

/// Response to 'stepBack' request. This is just an acknowledgement, so no body
/// field is required.
class StepBackResponse extends Response {
  static StepBackResponse fromJson(Map<String, Object?> obj) =>
      StepBackResponse.fromMap(obj);

  StepBackResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  StepBackResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'stepIn' request.
class StepInArguments extends RequestArguments {
  /// Optional granularity to step. If no granularity is specified, a
  /// granularity of 'statement' is assumed.
  final SteppingGranularity? granularity;

  /// Optional id of the target to step into.
  final int? targetId;

  /// Execute 'stepIn' for this thread.
  final int threadId;

  static StepInArguments fromJson(Map<String, Object?> obj) =>
      StepInArguments.fromMap(obj);

  StepInArguments({
    this.granularity,
    this.targetId,
    required this.threadId,
  });

  StepInArguments.fromMap(Map<String, Object?> obj)
      : granularity = obj['granularity'] as SteppingGranularity?,
        targetId = obj['targetId'] as int?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['granularity'] is! SteppingGranularity?) {
      return false;
    }
    if (obj['targetId'] is! int?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (granularity != null) 'granularity': granularity,
        if (targetId != null) 'targetId': targetId,
        'threadId': threadId,
      };
}

/// Response to 'stepIn' request. This is just an acknowledgement, so no body
/// field is required.
class StepInResponse extends Response {
  static StepInResponse fromJson(Map<String, Object?> obj) =>
      StepInResponse.fromMap(obj);

  StepInResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  StepInResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A StepInTarget can be used in the 'stepIn' request and determines into which
/// single target the stepIn request should step.
class StepInTarget {
  /// Unique identifier for a stepIn target.
  final int id;

  /// The name of the stepIn target (shown in the UI).
  final String label;

  static StepInTarget fromJson(Map<String, Object?> obj) =>
      StepInTarget.fromMap(obj);

  StepInTarget({
    required this.id,
    required this.label,
  });

  StepInTarget.fromMap(Map<String, Object?> obj)
      : id = obj['id'] as int,
        label = obj['label'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['id'] is! int) {
      return false;
    }
    if (obj['label'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'id': id,
        'label': label,
      };
}

/// Arguments for 'stepInTargets' request.
class StepInTargetsArguments extends RequestArguments {
  /// The stack frame for which to retrieve the possible stepIn targets.
  final int frameId;

  static StepInTargetsArguments fromJson(Map<String, Object?> obj) =>
      StepInTargetsArguments.fromMap(obj);

  StepInTargetsArguments({
    required this.frameId,
  });

  StepInTargetsArguments.fromMap(Map<String, Object?> obj)
      : frameId = obj['frameId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['frameId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'frameId': frameId,
      };
}

/// Response to 'stepInTargets' request.
class StepInTargetsResponse extends Response {
  static StepInTargetsResponse fromJson(Map<String, Object?> obj) =>
      StepInTargetsResponse.fromMap(obj);

  StepInTargetsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  StepInTargetsResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'stepOut' request.
class StepOutArguments extends RequestArguments {
  /// Optional granularity to step. If no granularity is specified, a
  /// granularity of 'statement' is assumed.
  final SteppingGranularity? granularity;

  /// Execute 'stepOut' for this thread.
  final int threadId;

  static StepOutArguments fromJson(Map<String, Object?> obj) =>
      StepOutArguments.fromMap(obj);

  StepOutArguments({
    this.granularity,
    required this.threadId,
  });

  StepOutArguments.fromMap(Map<String, Object?> obj)
      : granularity = obj['granularity'] as SteppingGranularity?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['granularity'] is! SteppingGranularity?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (granularity != null) 'granularity': granularity,
        'threadId': threadId,
      };
}

/// Response to 'stepOut' request. This is just an acknowledgement, so no body
/// field is required.
class StepOutResponse extends Response {
  static StepOutResponse fromJson(Map<String, Object?> obj) =>
      StepOutResponse.fromMap(obj);

  StepOutResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  StepOutResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// The granularity of one 'step' in the stepping requests 'next', 'stepIn',
/// 'stepOut', and 'stepBack'.
typedef SteppingGranularity = String;

/// Arguments for 'terminate' request.
class TerminateArguments extends RequestArguments {
  /// A value of true indicates that this 'terminate' request is part of a
  /// restart sequence.
  final bool? restart;

  static TerminateArguments fromJson(Map<String, Object?> obj) =>
      TerminateArguments.fromMap(obj);

  TerminateArguments({
    this.restart,
  });

  TerminateArguments.fromMap(Map<String, Object?> obj)
      : restart = obj['restart'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['restart'] is! bool?) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (restart != null) 'restart': restart,
      };
}

/// Response to 'terminate' request. This is just an acknowledgement, so no body
/// field is required.
class TerminateResponse extends Response {
  static TerminateResponse fromJson(Map<String, Object?> obj) =>
      TerminateResponse.fromMap(obj);

  TerminateResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  TerminateResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Arguments for 'terminateThreads' request.
class TerminateThreadsArguments extends RequestArguments {
  /// Ids of threads to be terminated.
  final List<int>? threadIds;

  static TerminateThreadsArguments fromJson(Map<String, Object?> obj) =>
      TerminateThreadsArguments.fromMap(obj);

  TerminateThreadsArguments({
    this.threadIds,
  });

  TerminateThreadsArguments.fromMap(Map<String, Object?> obj)
      : threadIds =
            (obj['threadIds'] as List?)?.map((item) => item as int).toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['threadIds'] is! List ||
        (obj['threadIds'].any((item) => item is! int)))) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (threadIds != null) 'threadIds': threadIds,
      };
}

/// Response to 'terminateThreads' request. This is just an acknowledgement, so
/// no body field is required.
class TerminateThreadsResponse extends Response {
  static TerminateThreadsResponse fromJson(Map<String, Object?> obj) =>
      TerminateThreadsResponse.fromMap(obj);

  TerminateThreadsResponse({
    Object? body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  TerminateThreadsResponse.fromMap(Map<String, Object?> obj)
      : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// A Thread
class Thread {
  /// Unique identifier for the thread.
  final int id;

  /// A name of the thread.
  final String name;

  static Thread fromJson(Map<String, Object?> obj) => Thread.fromMap(obj);

  Thread({
    required this.id,
    required this.name,
  });

  Thread.fromMap(Map<String, Object?> obj)
      : id = obj['id'] as int,
        name = obj['name'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['id'] is! int) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'id': id,
        'name': name,
      };
}

/// Response to 'threads' request.
class ThreadsResponse extends Response {
  static ThreadsResponse fromJson(Map<String, Object?> obj) =>
      ThreadsResponse.fromMap(obj);

  ThreadsResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  ThreadsResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Provides formatting information for a value.
class ValueFormat {
  /// Display the value in hex.
  final bool? hex;

  static ValueFormat fromJson(Map<String, Object?> obj) =>
      ValueFormat.fromMap(obj);

  ValueFormat({
    this.hex,
  });

  ValueFormat.fromMap(Map<String, Object?> obj) : hex = obj['hex'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['hex'] is! bool?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (hex != null) 'hex': hex,
      };
}

/// A Variable is a name/value pair.
/// Optionally a variable can have a 'type' that is shown if space permits or
/// when hovering over the variable's name.
/// An optional 'kind' is used to render additional properties of the variable,
/// e.g. different icons can be used to indicate that a variable is public or
/// private.
/// If the value is structured (has children), a handle is provided to retrieve
/// the children with the VariablesRequest.
/// If the number of named or indexed children is large, the numbers should be
/// returned via the optional 'namedVariables' and 'indexedVariables'
/// attributes.
/// The client can use this optional information to present the children in a
/// paged UI and fetch them in chunks.
class Variable {
  /// Optional evaluable name of this variable which can be passed to the
  /// 'EvaluateRequest' to fetch the variable's value.
  final String? evaluateName;

  /// The number of indexed child variables.
  /// The client can use this optional information to present the children in a
  /// paged UI and fetch them in chunks.
  final int? indexedVariables;

  /// Optional memory reference for the variable if the variable represents
  /// executable code, such as a function pointer.
  /// This attribute is only required if the client has passed the value true
  /// for the 'supportsMemoryReferences' capability of the 'initialize' request.
  final String? memoryReference;

  /// The variable's name.
  final String name;

  /// The number of named child variables.
  /// The client can use this optional information to present the children in a
  /// paged UI and fetch them in chunks.
  final int? namedVariables;

  /// Properties of a variable that can be used to determine how to render the
  /// variable in the UI.
  final VariablePresentationHint? presentationHint;

  /// The type of the variable's value. Typically shown in the UI when hovering
  /// over the value.
  /// This attribute should only be returned by a debug adapter if the client
  /// has passed the value true for the 'supportsVariableType' capability of the
  /// 'initialize' request.
  final String? type;

  /// The variable's value. This can be a multi-line text, e.g. for a function
  /// the body of a function.
  final String value;

  /// If variablesReference is > 0, the variable is structured and its children
  /// can be retrieved by passing variablesReference to the VariablesRequest.
  final int variablesReference;

  static Variable fromJson(Map<String, Object?> obj) => Variable.fromMap(obj);

  Variable({
    this.evaluateName,
    this.indexedVariables,
    this.memoryReference,
    required this.name,
    this.namedVariables,
    this.presentationHint,
    this.type,
    required this.value,
    required this.variablesReference,
  });

  Variable.fromMap(Map<String, Object?> obj)
      : evaluateName = obj['evaluateName'] as String?,
        indexedVariables = obj['indexedVariables'] as int?,
        memoryReference = obj['memoryReference'] as String?,
        name = obj['name'] as String,
        namedVariables = obj['namedVariables'] as int?,
        presentationHint = obj['presentationHint'] == null
            ? null
            : VariablePresentationHint.fromJson(
                obj['presentationHint'] as Map<String, Object?>),
        type = obj['type'] as String?,
        value = obj['value'] as String,
        variablesReference = obj['variablesReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['evaluateName'] is! String?) {
      return false;
    }
    if (obj['indexedVariables'] is! int?) {
      return false;
    }
    if (obj['memoryReference'] is! String?) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['namedVariables'] is! int?) {
      return false;
    }
    if (!VariablePresentationHint.canParse(obj['presentationHint'])) {
      return false;
    }
    if (obj['type'] is! String?) {
      return false;
    }
    if (obj['value'] is! String) {
      return false;
    }
    if (obj['variablesReference'] is! int) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (evaluateName != null) 'evaluateName': evaluateName,
        if (indexedVariables != null) 'indexedVariables': indexedVariables,
        if (memoryReference != null) 'memoryReference': memoryReference,
        'name': name,
        if (namedVariables != null) 'namedVariables': namedVariables,
        if (presentationHint != null) 'presentationHint': presentationHint,
        if (type != null) 'type': type,
        'value': value,
        'variablesReference': variablesReference,
      };
}

/// Optional properties of a variable that can be used to determine how to
/// render the variable in the UI.
class VariablePresentationHint {
  /// Set of attributes represented as an array of strings. Before introducing
  /// additional values, try to use the listed values.
  final List<String>? attributes;

  /// The kind of variable. Before introducing additional values, try to use the
  /// listed values.
  final String? kind;

  /// Visibility of variable. Before introducing additional values, try to use
  /// the listed values.
  final String? visibility;

  static VariablePresentationHint fromJson(Map<String, Object?> obj) =>
      VariablePresentationHint.fromMap(obj);

  VariablePresentationHint({
    this.attributes,
    this.kind,
    this.visibility,
  });

  VariablePresentationHint.fromMap(Map<String, Object?> obj)
      : attributes = (obj['attributes'] as List?)
            ?.map((item) => item as String)
            .toList(),
        kind = obj['kind'] as String?,
        visibility = obj['visibility'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['attributes'] is! List ||
        (obj['attributes'].any((item) => item is! String)))) {
      return false;
    }
    if (obj['kind'] is! String?) {
      return false;
    }
    if (obj['visibility'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (attributes != null) 'attributes': attributes,
        if (kind != null) 'kind': kind,
        if (visibility != null) 'visibility': visibility,
      };
}

/// Arguments for 'variables' request.
class VariablesArguments extends RequestArguments {
  /// The number of variables to return. If count is missing or 0, all variables
  /// are returned.
  final int? count;

  /// Optional filter to limit the child variables to either named or indexed.
  /// If omitted, both types are fetched.
  final String? filter;

  /// Specifies details on how to format the Variable values.
  /// The attribute is only honored by a debug adapter if the capability
  /// 'supportsValueFormattingOptions' is true.
  final ValueFormat? format;

  /// The index of the first variable to return; if omitted children start at 0.
  final int? start;

  /// The Variable reference.
  final int variablesReference;

  static VariablesArguments fromJson(Map<String, Object?> obj) =>
      VariablesArguments.fromMap(obj);

  VariablesArguments({
    this.count,
    this.filter,
    this.format,
    this.start,
    required this.variablesReference,
  });

  VariablesArguments.fromMap(Map<String, Object?> obj)
      : count = obj['count'] as int?,
        filter = obj['filter'] as String?,
        format = obj['format'] == null
            ? null
            : ValueFormat.fromJson(obj['format'] as Map<String, Object?>),
        start = obj['start'] as int?,
        variablesReference = obj['variablesReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['count'] is! int?) {
      return false;
    }
    if (obj['filter'] is! String?) {
      return false;
    }
    if (!ValueFormat.canParse(obj['format'])) {
      return false;
    }
    if (obj['start'] is! int?) {
      return false;
    }
    if (obj['variablesReference'] is! int) {
      return false;
    }
    return RequestArguments.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (count != null) 'count': count,
        if (filter != null) 'filter': filter,
        if (format != null) 'format': format,
        if (start != null) 'start': start,
        'variablesReference': variablesReference,
      };
}

/// Response to 'variables' request.
class VariablesResponse extends Response {
  static VariablesResponse fromJson(Map<String, Object?> obj) =>
      VariablesResponse.fromMap(obj);

  VariablesResponse({
    required Map<String, Object?> body,
    required String command,
    String? message,
    required int requestSeq,
    required int seq,
    required bool success,
  }) : super(
          seq: seq,
          requestSeq: requestSeq,
          success: success,
          command: command,
          message: message,
          body: body,
        );

  VariablesResponse.fromMap(Map<String, Object?> obj) : super.fromMap(obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['body'] is! Map<String, Object?>) {
      return false;
    }
    return Response.canParse(obj);
  }

  @override
  Map<String, Object?> toJson() => {
        ...super.toJson(),
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class AttachResponseBody {
  static AttachResponseBody fromJson(Map<String, Object?> obj) =>
      AttachResponseBody.fromMap(obj);

  AttachResponseBody();

  AttachResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class BreakpointEventBody extends EventBody {
  /// The 'id' attribute is used to find the target breakpoint and the other
  /// attributes are used as the new values.
  final Breakpoint breakpoint;

  /// The reason for the event.
  final String reason;

  static BreakpointEventBody fromJson(Map<String, Object?> obj) =>
      BreakpointEventBody.fromMap(obj);

  BreakpointEventBody({
    required this.breakpoint,
    required this.reason,
  });

  BreakpointEventBody.fromMap(Map<String, Object?> obj)
      : breakpoint =
            Breakpoint.fromJson(obj['breakpoint'] as Map<String, Object?>),
        reason = obj['reason'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Breakpoint.canParse(obj['breakpoint'])) {
      return false;
    }
    if (obj['reason'] is! String) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'breakpoint': breakpoint,
        'reason': reason,
      };
}

class BreakpointLocationsResponseBody {
  /// Sorted set of possible breakpoint locations.
  final List<BreakpointLocation> breakpoints;

  static BreakpointLocationsResponseBody fromJson(Map<String, Object?> obj) =>
      BreakpointLocationsResponseBody.fromMap(obj);

  BreakpointLocationsResponseBody({
    required this.breakpoints,
  });

  BreakpointLocationsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) =>
                BreakpointLocation.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints']
            .any((item) => !BreakpointLocation.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class CancelResponseBody {
  static CancelResponseBody fromJson(Map<String, Object?> obj) =>
      CancelResponseBody.fromMap(obj);

  CancelResponseBody();

  CancelResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class CapabilitiesEventBody extends EventBody {
  /// The set of updated capabilities.
  final Capabilities capabilities;

  static CapabilitiesEventBody fromJson(Map<String, Object?> obj) =>
      CapabilitiesEventBody.fromMap(obj);

  CapabilitiesEventBody({
    required this.capabilities,
  });

  CapabilitiesEventBody.fromMap(Map<String, Object?> obj)
      : capabilities =
            Capabilities.fromJson(obj['capabilities'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Capabilities.canParse(obj['capabilities'])) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'capabilities': capabilities,
      };
}

class CompletionsResponseBody {
  /// The possible completions for .
  final List<CompletionItem> targets;

  static CompletionsResponseBody fromJson(Map<String, Object?> obj) =>
      CompletionsResponseBody.fromMap(obj);

  CompletionsResponseBody({
    required this.targets,
  });

  CompletionsResponseBody.fromMap(Map<String, Object?> obj)
      : targets = (obj['targets'] as List)
            .map(
                (item) => CompletionItem.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['targets'] is! List ||
        (obj['targets'].any((item) => !CompletionItem.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'targets': targets,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class ConfigurationDoneResponseBody {
  static ConfigurationDoneResponseBody fromJson(Map<String, Object?> obj) =>
      ConfigurationDoneResponseBody.fromMap(obj);

  ConfigurationDoneResponseBody();

  ConfigurationDoneResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class ContinueResponseBody {
  /// If true, the 'continue' request has ignored the specified thread and
  /// continued all threads instead.
  /// If this attribute is missing a value of 'true' is assumed for backward
  /// compatibility.
  final bool? allThreadsContinued;

  static ContinueResponseBody fromJson(Map<String, Object?> obj) =>
      ContinueResponseBody.fromMap(obj);

  ContinueResponseBody({
    this.allThreadsContinued,
  });

  ContinueResponseBody.fromMap(Map<String, Object?> obj)
      : allThreadsContinued = obj['allThreadsContinued'] as bool?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['allThreadsContinued'] is! bool?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (allThreadsContinued != null)
          'allThreadsContinued': allThreadsContinued,
      };
}

class ContinuedEventBody extends EventBody {
  /// If 'allThreadsContinued' is true, a debug adapter can announce that all
  /// threads have continued.
  final bool? allThreadsContinued;

  /// The thread which was continued.
  final int threadId;

  static ContinuedEventBody fromJson(Map<String, Object?> obj) =>
      ContinuedEventBody.fromMap(obj);

  ContinuedEventBody({
    this.allThreadsContinued,
    required this.threadId,
  });

  ContinuedEventBody.fromMap(Map<String, Object?> obj)
      : allThreadsContinued = obj['allThreadsContinued'] as bool?,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['allThreadsContinued'] is! bool?) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (allThreadsContinued != null)
          'allThreadsContinued': allThreadsContinued,
        'threadId': threadId,
      };
}

class DataBreakpointInfoResponseBody {
  /// Optional attribute listing the available access types for a potential data
  /// breakpoint. A UI frontend could surface this information.
  final List<DataBreakpointAccessType>? accessTypes;

  /// Optional attribute indicating that a potential data breakpoint could be
  /// persisted across sessions.
  final bool? canPersist;

  /// An identifier for the data on which a data breakpoint can be registered
  /// with the setDataBreakpoints request or null if no data breakpoint is
  /// available.
  final Either2<String, Null> dataId;

  /// UI string that describes on what data the breakpoint is set on or why a
  /// data breakpoint is not available.
  final String description;

  static DataBreakpointInfoResponseBody fromJson(Map<String, Object?> obj) =>
      DataBreakpointInfoResponseBody.fromMap(obj);

  DataBreakpointInfoResponseBody({
    this.accessTypes,
    this.canPersist,
    required this.dataId,
    required this.description,
  });

  DataBreakpointInfoResponseBody.fromMap(Map<String, Object?> obj)
      : accessTypes = (obj['accessTypes'] as List?)
            ?.map((item) => item as DataBreakpointAccessType)
            .toList(),
        canPersist = obj['canPersist'] as bool?,
        dataId = obj['dataId'] is String
            ? Either2<String, Null>.t1(obj['dataId'] as String)
            : Either2<String, Null>.t2(obj['dataId'] as Null),
        description = obj['description'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['accessTypes'] is! List ||
        (obj['accessTypes']
            .any((item) => item is! DataBreakpointAccessType)))) {
      return false;
    }
    if (obj['canPersist'] is! bool?) {
      return false;
    }
    if ((obj['dataId'] is! String && obj['dataId'] != null)) {
      return false;
    }
    if (obj['description'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (accessTypes != null) 'accessTypes': accessTypes,
        if (canPersist != null) 'canPersist': canPersist,
        'dataId': dataId,
        'description': description,
      };
}

class DisassembleResponseBody {
  /// The list of disassembled instructions.
  final List<DisassembledInstruction> instructions;

  static DisassembleResponseBody fromJson(Map<String, Object?> obj) =>
      DisassembleResponseBody.fromMap(obj);

  DisassembleResponseBody({
    required this.instructions,
  });

  DisassembleResponseBody.fromMap(Map<String, Object?> obj)
      : instructions = (obj['instructions'] as List)
            .map((item) =>
                DisassembledInstruction.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['instructions'] is! List ||
        (obj['instructions']
            .any((item) => !DisassembledInstruction.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'instructions': instructions,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class DisconnectResponseBody {
  static DisconnectResponseBody fromJson(Map<String, Object?> obj) =>
      DisconnectResponseBody.fromMap(obj);

  DisconnectResponseBody();

  DisconnectResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class ErrorResponseBody {
  /// An optional, structured error message.
  final Message? error;

  static ErrorResponseBody fromJson(Map<String, Object?> obj) =>
      ErrorResponseBody.fromMap(obj);

  ErrorResponseBody({
    this.error,
  });

  ErrorResponseBody.fromMap(Map<String, Object?> obj)
      : error = obj['error'] == null
            ? null
            : Message.fromJson(obj['error'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Message.canParse(obj['error'])) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (error != null) 'error': error,
      };
}

class EvaluateResponseBody {
  /// The number of indexed child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? indexedVariables;

  /// Optional memory reference to a location appropriate for this result.
  /// For pointer type eval results, this is generally a reference to the memory
  /// address contained in the pointer.
  /// This attribute should be returned by a debug adapter if the client has
  /// passed the value true for the 'supportsMemoryReferences' capability of the
  /// 'initialize' request.
  final String? memoryReference;

  /// The number of named child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? namedVariables;

  /// Properties of a evaluate result that can be used to determine how to
  /// render the result in the UI.
  final VariablePresentationHint? presentationHint;

  /// The result of the evaluate request.
  final String result;

  /// The optional type of the evaluate result.
  /// This attribute should only be returned by a debug adapter if the client
  /// has passed the value true for the 'supportsVariableType' capability of the
  /// 'initialize' request.
  final String? type;

  /// If variablesReference is > 0, the evaluate result is structured and its
  /// children can be retrieved by passing variablesReference to the
  /// VariablesRequest.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int variablesReference;

  static EvaluateResponseBody fromJson(Map<String, Object?> obj) =>
      EvaluateResponseBody.fromMap(obj);

  EvaluateResponseBody({
    this.indexedVariables,
    this.memoryReference,
    this.namedVariables,
    this.presentationHint,
    required this.result,
    this.type,
    required this.variablesReference,
  });

  EvaluateResponseBody.fromMap(Map<String, Object?> obj)
      : indexedVariables = obj['indexedVariables'] as int?,
        memoryReference = obj['memoryReference'] as String?,
        namedVariables = obj['namedVariables'] as int?,
        presentationHint = obj['presentationHint'] == null
            ? null
            : VariablePresentationHint.fromJson(
                obj['presentationHint'] as Map<String, Object?>),
        result = obj['result'] as String,
        type = obj['type'] as String?,
        variablesReference = obj['variablesReference'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['indexedVariables'] is! int?) {
      return false;
    }
    if (obj['memoryReference'] is! String?) {
      return false;
    }
    if (obj['namedVariables'] is! int?) {
      return false;
    }
    if (!VariablePresentationHint.canParse(obj['presentationHint'])) {
      return false;
    }
    if (obj['result'] is! String) {
      return false;
    }
    if (obj['type'] is! String?) {
      return false;
    }
    if (obj['variablesReference'] is! int) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (indexedVariables != null) 'indexedVariables': indexedVariables,
        if (memoryReference != null) 'memoryReference': memoryReference,
        if (namedVariables != null) 'namedVariables': namedVariables,
        if (presentationHint != null) 'presentationHint': presentationHint,
        'result': result,
        if (type != null) 'type': type,
        'variablesReference': variablesReference,
      };
}

class ExceptionInfoResponseBody {
  /// Mode that caused the exception notification to be raised.
  final ExceptionBreakMode breakMode;

  /// Descriptive text for the exception provided by the debug adapter.
  final String? description;

  /// Detailed information about the exception.
  final ExceptionDetails? details;

  /// ID of the exception that was thrown.
  final String exceptionId;

  static ExceptionInfoResponseBody fromJson(Map<String, Object?> obj) =>
      ExceptionInfoResponseBody.fromMap(obj);

  ExceptionInfoResponseBody({
    required this.breakMode,
    this.description,
    this.details,
    required this.exceptionId,
  });

  ExceptionInfoResponseBody.fromMap(Map<String, Object?> obj)
      : breakMode = obj['breakMode'] as ExceptionBreakMode,
        description = obj['description'] as String?,
        details = obj['details'] == null
            ? null
            : ExceptionDetails.fromJson(obj['details'] as Map<String, Object?>),
        exceptionId = obj['exceptionId'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['breakMode'] is! ExceptionBreakMode) {
      return false;
    }
    if (obj['description'] is! String?) {
      return false;
    }
    if (!ExceptionDetails.canParse(obj['details'])) {
      return false;
    }
    if (obj['exceptionId'] is! String) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakMode': breakMode,
        if (description != null) 'description': description,
        if (details != null) 'details': details,
        'exceptionId': exceptionId,
      };
}

class ExitedEventBody extends EventBody {
  /// The exit code returned from the debuggee.
  final int exitCode;

  static ExitedEventBody fromJson(Map<String, Object?> obj) =>
      ExitedEventBody.fromMap(obj);

  ExitedEventBody({
    required this.exitCode,
  });

  ExitedEventBody.fromMap(Map<String, Object?> obj)
      : exitCode = obj['exitCode'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['exitCode'] is! int) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'exitCode': exitCode,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class GotoResponseBody {
  static GotoResponseBody fromJson(Map<String, Object?> obj) =>
      GotoResponseBody.fromMap(obj);

  GotoResponseBody();

  GotoResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class GotoTargetsResponseBody {
  /// The possible goto targets of the specified location.
  final List<GotoTarget> targets;

  static GotoTargetsResponseBody fromJson(Map<String, Object?> obj) =>
      GotoTargetsResponseBody.fromMap(obj);

  GotoTargetsResponseBody({
    required this.targets,
  });

  GotoTargetsResponseBody.fromMap(Map<String, Object?> obj)
      : targets = (obj['targets'] as List)
            .map((item) => GotoTarget.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['targets'] is! List ||
        (obj['targets'].any((item) => !GotoTarget.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'targets': targets,
      };
}

/// The capabilities of this debug adapter.
class InitializeResponseBody {
  static InitializeResponseBody fromJson(Map<String, Object?> obj) =>
      InitializeResponseBody.fromMap(obj);

  InitializeResponseBody();

  InitializeResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

/// Event-specific information.
class InitializedEventBody extends EventBody {
  static InitializedEventBody fromJson(Map<String, Object?> obj) =>
      InitializedEventBody.fromMap(obj);

  InitializedEventBody();

  InitializedEventBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {};
}

class InvalidatedEventBody extends EventBody {
  /// Optional set of logical areas that got invalidated. This property has a
  /// hint characteristic: a client can only be expected to make a 'best effort'
  /// in honouring the areas but there are no guarantees. If this property is
  /// missing, empty, or if values are not understand the client should assume a
  /// single value 'all'.
  final List<InvalidatedAreas>? areas;

  /// If specified, the client only needs to refetch data related to this stack
  /// frame (and the 'threadId' is ignored).
  final int? stackFrameId;

  /// If specified, the client only needs to refetch data related to this
  /// thread.
  final int? threadId;

  static InvalidatedEventBody fromJson(Map<String, Object?> obj) =>
      InvalidatedEventBody.fromMap(obj);

  InvalidatedEventBody({
    this.areas,
    this.stackFrameId,
    this.threadId,
  });

  InvalidatedEventBody.fromMap(Map<String, Object?> obj)
      : areas = (obj['areas'] as List?)
            ?.map((item) => item as InvalidatedAreas)
            .toList(),
        stackFrameId = obj['stackFrameId'] as int?,
        threadId = obj['threadId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['areas'] is! List ||
        (obj['areas'].any((item) => item is! InvalidatedAreas)))) {
      return false;
    }
    if (obj['stackFrameId'] is! int?) {
      return false;
    }
    if (obj['threadId'] is! int?) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (areas != null) 'areas': areas,
        if (stackFrameId != null) 'stackFrameId': stackFrameId,
        if (threadId != null) 'threadId': threadId,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class LaunchResponseBody {
  static LaunchResponseBody fromJson(Map<String, Object?> obj) =>
      LaunchResponseBody.fromMap(obj);

  LaunchResponseBody();

  LaunchResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class LoadedSourceEventBody extends EventBody {
  /// The reason for the event.
  final String reason;

  /// The new, changed, or removed source.
  final Source source;

  static LoadedSourceEventBody fromJson(Map<String, Object?> obj) =>
      LoadedSourceEventBody.fromMap(obj);

  LoadedSourceEventBody({
    required this.reason,
    required this.source,
  });

  LoadedSourceEventBody.fromMap(Map<String, Object?> obj)
      : reason = obj['reason'] as String,
        source = Source.fromJson(obj['source'] as Map<String, Object?>);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['reason'] is! String) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'reason': reason,
        'source': source,
      };
}

class LoadedSourcesResponseBody {
  /// Set of loaded sources.
  final List<Source> sources;

  static LoadedSourcesResponseBody fromJson(Map<String, Object?> obj) =>
      LoadedSourcesResponseBody.fromMap(obj);

  LoadedSourcesResponseBody({
    required this.sources,
  });

  LoadedSourcesResponseBody.fromMap(Map<String, Object?> obj)
      : sources = (obj['sources'] as List)
            .map((item) => Source.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['sources'] is! List ||
        (obj['sources'].any((item) => !Source.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'sources': sources,
      };
}

class ModuleEventBody extends EventBody {
  /// The new, changed, or removed module. In case of 'removed' only the module
  /// id is used.
  final Module module;

  /// The reason for the event.
  final String reason;

  static ModuleEventBody fromJson(Map<String, Object?> obj) =>
      ModuleEventBody.fromMap(obj);

  ModuleEventBody({
    required this.module,
    required this.reason,
  });

  ModuleEventBody.fromMap(Map<String, Object?> obj)
      : module = Module.fromJson(obj['module'] as Map<String, Object?>),
        reason = obj['reason'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (!Module.canParse(obj['module'])) {
      return false;
    }
    if (obj['reason'] is! String) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'module': module,
        'reason': reason,
      };
}

class ModulesResponseBody {
  /// All modules or range of modules.
  final List<Module> modules;

  /// The total number of modules available.
  final int? totalModules;

  static ModulesResponseBody fromJson(Map<String, Object?> obj) =>
      ModulesResponseBody.fromMap(obj);

  ModulesResponseBody({
    required this.modules,
    this.totalModules,
  });

  ModulesResponseBody.fromMap(Map<String, Object?> obj)
      : modules = (obj['modules'] as List)
            .map((item) => Module.fromJson(item as Map<String, Object?>))
            .toList(),
        totalModules = obj['totalModules'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['modules'] is! List ||
        (obj['modules'].any((item) => !Module.canParse(item))))) {
      return false;
    }
    if (obj['totalModules'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'modules': modules,
        if (totalModules != null) 'totalModules': totalModules,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class NextResponseBody {
  static NextResponseBody fromJson(Map<String, Object?> obj) =>
      NextResponseBody.fromMap(obj);

  NextResponseBody();

  NextResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class OutputEventBody extends EventBody {
  /// The output category. If not specified, 'console' is assumed.
  final String? category;

  /// An optional source location column where the output was produced.
  final int? column;

  /// Optional data to report. For the 'telemetry' category the data will be
  /// sent to telemetry, for the other categories the data is shown in JSON
  /// format.
  final Object? data;

  /// Support for keeping an output log organized by grouping related messages.
  final String? group;

  /// An optional source location line where the output was produced.
  final int? line;

  /// The output to report.
  final String output;

  /// An optional source location where the output was produced.
  final Source? source;

  /// If an attribute 'variablesReference' exists and its value is > 0, the
  /// output contains objects which can be retrieved by passing
  /// 'variablesReference' to the 'variables' request. The value should be less
  /// than or equal to 2147483647 (2^31-1).
  final int? variablesReference;

  static OutputEventBody fromJson(Map<String, Object?> obj) =>
      OutputEventBody.fromMap(obj);

  OutputEventBody({
    this.category,
    this.column,
    this.data,
    this.group,
    this.line,
    required this.output,
    this.source,
    this.variablesReference,
  });

  OutputEventBody.fromMap(Map<String, Object?> obj)
      : category = obj['category'] as String?,
        column = obj['column'] as int?,
        data = obj['data'],
        group = obj['group'] as String?,
        line = obj['line'] as int?,
        output = obj['output'] as String,
        source = obj['source'] == null
            ? null
            : Source.fromJson(obj['source'] as Map<String, Object?>),
        variablesReference = obj['variablesReference'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['category'] is! String?) {
      return false;
    }
    if (obj['column'] is! int?) {
      return false;
    }
    if (obj['group'] is! String?) {
      return false;
    }
    if (obj['line'] is! int?) {
      return false;
    }
    if (obj['output'] is! String) {
      return false;
    }
    if (!Source.canParse(obj['source'])) {
      return false;
    }
    if (obj['variablesReference'] is! int?) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (category != null) 'category': category,
        if (column != null) 'column': column,
        if (data != null) 'data': data,
        if (group != null) 'group': group,
        if (line != null) 'line': line,
        'output': output,
        if (source != null) 'source': source,
        if (variablesReference != null)
          'variablesReference': variablesReference,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class PauseResponseBody {
  static PauseResponseBody fromJson(Map<String, Object?> obj) =>
      PauseResponseBody.fromMap(obj);

  PauseResponseBody();

  PauseResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class ProcessEventBody extends EventBody {
  /// If true, the process is running on the same computer as the debug adapter.
  final bool? isLocalProcess;

  /// The logical name of the process. This is usually the full path to
  /// process's executable file. Example: /home/example/myproj/program.js.
  final String name;

  /// The size of a pointer or address for this process, in bits. This value may
  /// be used by clients when formatting addresses for display.
  final int? pointerSize;

  /// Describes how the debug engine started debugging this process.
  final String? startMethod;

  /// The system process id of the debugged process. This property will be
  /// missing for non-system processes.
  final int? systemProcessId;

  static ProcessEventBody fromJson(Map<String, Object?> obj) =>
      ProcessEventBody.fromMap(obj);

  ProcessEventBody({
    this.isLocalProcess,
    required this.name,
    this.pointerSize,
    this.startMethod,
    this.systemProcessId,
  });

  ProcessEventBody.fromMap(Map<String, Object?> obj)
      : isLocalProcess = obj['isLocalProcess'] as bool?,
        name = obj['name'] as String,
        pointerSize = obj['pointerSize'] as int?,
        startMethod = obj['startMethod'] as String?,
        systemProcessId = obj['systemProcessId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['isLocalProcess'] is! bool?) {
      return false;
    }
    if (obj['name'] is! String) {
      return false;
    }
    if (obj['pointerSize'] is! int?) {
      return false;
    }
    if (obj['startMethod'] is! String?) {
      return false;
    }
    if (obj['systemProcessId'] is! int?) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (isLocalProcess != null) 'isLocalProcess': isLocalProcess,
        'name': name,
        if (pointerSize != null) 'pointerSize': pointerSize,
        if (startMethod != null) 'startMethod': startMethod,
        if (systemProcessId != null) 'systemProcessId': systemProcessId,
      };
}

class ProgressEndEventBody extends EventBody {
  /// Optional, more detailed progress message. If omitted, the previous message
  /// (if any) is used.
  final String? message;

  /// The ID that was introduced in the initial 'ProgressStartEvent'.
  final String progressId;

  static ProgressEndEventBody fromJson(Map<String, Object?> obj) =>
      ProgressEndEventBody.fromMap(obj);

  ProgressEndEventBody({
    this.message,
    required this.progressId,
  });

  ProgressEndEventBody.fromMap(Map<String, Object?> obj)
      : message = obj['message'] as String?,
        progressId = obj['progressId'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['progressId'] is! String) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (message != null) 'message': message,
        'progressId': progressId,
      };
}

class ProgressStartEventBody extends EventBody {
  /// If true, the request that reports progress may be canceled with a 'cancel'
  /// request.
  /// So this property basically controls whether the client should use UX that
  /// supports cancellation.
  /// Clients that don't support cancellation are allowed to ignore the setting.
  final bool? cancellable;

  /// Optional, more detailed progress message.
  final String? message;

  /// Optional progress percentage to display (value range: 0 to 100). If
  /// omitted no percentage will be shown.
  final num? percentage;

  /// An ID that must be used in subsequent 'progressUpdate' and 'progressEnd'
  /// events to make them refer to the same progress reporting.
  /// IDs must be unique within a debug session.
  final String progressId;

  /// The request ID that this progress report is related to. If specified a
  /// debug adapter is expected to emit
  /// progress events for the long running request until the request has been
  /// either completed or cancelled.
  /// If the request ID is omitted, the progress report is assumed to be related
  /// to some general activity of the debug adapter.
  final int? requestId;

  /// Mandatory (short) title of the progress reporting. Shown in the UI to
  /// describe the long running operation.
  final String title;

  static ProgressStartEventBody fromJson(Map<String, Object?> obj) =>
      ProgressStartEventBody.fromMap(obj);

  ProgressStartEventBody({
    this.cancellable,
    this.message,
    this.percentage,
    required this.progressId,
    this.requestId,
    required this.title,
  });

  ProgressStartEventBody.fromMap(Map<String, Object?> obj)
      : cancellable = obj['cancellable'] as bool?,
        message = obj['message'] as String?,
        percentage = obj['percentage'] as num?,
        progressId = obj['progressId'] as String,
        requestId = obj['requestId'] as int?,
        title = obj['title'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['cancellable'] is! bool?) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['percentage'] is! num?) {
      return false;
    }
    if (obj['progressId'] is! String) {
      return false;
    }
    if (obj['requestId'] is! int?) {
      return false;
    }
    if (obj['title'] is! String) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (cancellable != null) 'cancellable': cancellable,
        if (message != null) 'message': message,
        if (percentage != null) 'percentage': percentage,
        'progressId': progressId,
        if (requestId != null) 'requestId': requestId,
        'title': title,
      };
}

class ProgressUpdateEventBody extends EventBody {
  /// Optional, more detailed progress message. If omitted, the previous message
  /// (if any) is used.
  final String? message;

  /// Optional progress percentage to display (value range: 0 to 100). If
  /// omitted no percentage will be shown.
  final num? percentage;

  /// The ID that was introduced in the initial 'progressStart' event.
  final String progressId;

  static ProgressUpdateEventBody fromJson(Map<String, Object?> obj) =>
      ProgressUpdateEventBody.fromMap(obj);

  ProgressUpdateEventBody({
    this.message,
    this.percentage,
    required this.progressId,
  });

  ProgressUpdateEventBody.fromMap(Map<String, Object?> obj)
      : message = obj['message'] as String?,
        percentage = obj['percentage'] as num?,
        progressId = obj['progressId'] as String;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['message'] is! String?) {
      return false;
    }
    if (obj['percentage'] is! num?) {
      return false;
    }
    if (obj['progressId'] is! String) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (message != null) 'message': message,
        if (percentage != null) 'percentage': percentage,
        'progressId': progressId,
      };
}

class ReadMemoryResponseBody {
  /// The address of the first byte of data returned.
  /// Treated as a hex value if prefixed with '0x', or as a decimal value
  /// otherwise.
  final String address;

  /// The bytes read from memory, encoded using base64.
  final String? data;

  /// The number of unreadable bytes encountered after the last successfully
  /// read byte.
  /// This can be used to determine the number of bytes that must be skipped
  /// before a subsequent 'readMemory' request will succeed.
  final int? unreadableBytes;

  static ReadMemoryResponseBody fromJson(Map<String, Object?> obj) =>
      ReadMemoryResponseBody.fromMap(obj);

  ReadMemoryResponseBody({
    required this.address,
    this.data,
    this.unreadableBytes,
  });

  ReadMemoryResponseBody.fromMap(Map<String, Object?> obj)
      : address = obj['address'] as String,
        data = obj['data'] as String?,
        unreadableBytes = obj['unreadableBytes'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['address'] is! String) {
      return false;
    }
    if (obj['data'] is! String?) {
      return false;
    }
    if (obj['unreadableBytes'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'address': address,
        if (data != null) 'data': data,
        if (unreadableBytes != null) 'unreadableBytes': unreadableBytes,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class RestartFrameResponseBody {
  static RestartFrameResponseBody fromJson(Map<String, Object?> obj) =>
      RestartFrameResponseBody.fromMap(obj);

  RestartFrameResponseBody();

  RestartFrameResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

/// Contains request result if success is true and optional error details if
/// success is false.
class RestartResponseBody {
  static RestartResponseBody fromJson(Map<String, Object?> obj) =>
      RestartResponseBody.fromMap(obj);

  RestartResponseBody();

  RestartResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

/// Contains request result if success is true and optional error details if
/// success is false.
class ReverseContinueResponseBody {
  static ReverseContinueResponseBody fromJson(Map<String, Object?> obj) =>
      ReverseContinueResponseBody.fromMap(obj);

  ReverseContinueResponseBody();

  ReverseContinueResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class RunInTerminalResponseBody {
  /// The process ID. The value should be less than or equal to 2147483647
  /// (2^31-1).
  final int? processId;

  /// The process ID of the terminal shell. The value should be less than or
  /// equal to 2147483647 (2^31-1).
  final int? shellProcessId;

  static RunInTerminalResponseBody fromJson(Map<String, Object?> obj) =>
      RunInTerminalResponseBody.fromMap(obj);

  RunInTerminalResponseBody({
    this.processId,
    this.shellProcessId,
  });

  RunInTerminalResponseBody.fromMap(Map<String, Object?> obj)
      : processId = obj['processId'] as int?,
        shellProcessId = obj['shellProcessId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['processId'] is! int?) {
      return false;
    }
    if (obj['shellProcessId'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (processId != null) 'processId': processId,
        if (shellProcessId != null) 'shellProcessId': shellProcessId,
      };
}

class ScopesResponseBody {
  /// The scopes of the stackframe. If the array has length zero, there are no
  /// scopes available.
  final List<Scope> scopes;

  static ScopesResponseBody fromJson(Map<String, Object?> obj) =>
      ScopesResponseBody.fromMap(obj);

  ScopesResponseBody({
    required this.scopes,
  });

  ScopesResponseBody.fromMap(Map<String, Object?> obj)
      : scopes = (obj['scopes'] as List)
            .map((item) => Scope.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['scopes'] is! List ||
        (obj['scopes'].any((item) => !Scope.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'scopes': scopes,
      };
}

class SetBreakpointsResponseBody {
  /// Information about the breakpoints.
  /// The array elements are in the same order as the elements of the
  /// 'breakpoints' (or the deprecated 'lines') array in the arguments.
  final List<Breakpoint> breakpoints;

  static SetBreakpointsResponseBody fromJson(Map<String, Object?> obj) =>
      SetBreakpointsResponseBody.fromMap(obj);

  SetBreakpointsResponseBody({
    required this.breakpoints,
  });

  SetBreakpointsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) => Breakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !Breakpoint.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

class SetDataBreakpointsResponseBody {
  /// Information about the data breakpoints. The array elements correspond to
  /// the elements of the input argument 'breakpoints' array.
  final List<Breakpoint> breakpoints;

  static SetDataBreakpointsResponseBody fromJson(Map<String, Object?> obj) =>
      SetDataBreakpointsResponseBody.fromMap(obj);

  SetDataBreakpointsResponseBody({
    required this.breakpoints,
  });

  SetDataBreakpointsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) => Breakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !Breakpoint.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

class SetExceptionBreakpointsResponseBody {
  /// Information about the exception breakpoints or filters.
  /// The breakpoints returned are in the same order as the elements of the
  /// 'filters', 'filterOptions', 'exceptionOptions' arrays in the arguments. If
  /// both 'filters' and 'filterOptions' are given, the returned array must
  /// start with 'filters' information first, followed by 'filterOptions'
  /// information.
  final List<Breakpoint>? breakpoints;

  static SetExceptionBreakpointsResponseBody fromJson(
          Map<String, Object?> obj) =>
      SetExceptionBreakpointsResponseBody.fromMap(obj);

  SetExceptionBreakpointsResponseBody({
    this.breakpoints,
  });

  SetExceptionBreakpointsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List?)
            ?.map((item) => Breakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !Breakpoint.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (breakpoints != null) 'breakpoints': breakpoints,
      };
}

class SetExpressionResponseBody {
  /// The number of indexed child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? indexedVariables;

  /// The number of named child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? namedVariables;

  /// Properties of a value that can be used to determine how to render the
  /// result in the UI.
  final VariablePresentationHint? presentationHint;

  /// The optional type of the value.
  /// This attribute should only be returned by a debug adapter if the client
  /// has passed the value true for the 'supportsVariableType' capability of the
  /// 'initialize' request.
  final String? type;

  /// The new value of the expression.
  final String value;

  /// If variablesReference is > 0, the value is structured and its children can
  /// be retrieved by passing variablesReference to the VariablesRequest.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? variablesReference;

  static SetExpressionResponseBody fromJson(Map<String, Object?> obj) =>
      SetExpressionResponseBody.fromMap(obj);

  SetExpressionResponseBody({
    this.indexedVariables,
    this.namedVariables,
    this.presentationHint,
    this.type,
    required this.value,
    this.variablesReference,
  });

  SetExpressionResponseBody.fromMap(Map<String, Object?> obj)
      : indexedVariables = obj['indexedVariables'] as int?,
        namedVariables = obj['namedVariables'] as int?,
        presentationHint = obj['presentationHint'] == null
            ? null
            : VariablePresentationHint.fromJson(
                obj['presentationHint'] as Map<String, Object?>),
        type = obj['type'] as String?,
        value = obj['value'] as String,
        variablesReference = obj['variablesReference'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['indexedVariables'] is! int?) {
      return false;
    }
    if (obj['namedVariables'] is! int?) {
      return false;
    }
    if (!VariablePresentationHint.canParse(obj['presentationHint'])) {
      return false;
    }
    if (obj['type'] is! String?) {
      return false;
    }
    if (obj['value'] is! String) {
      return false;
    }
    if (obj['variablesReference'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (indexedVariables != null) 'indexedVariables': indexedVariables,
        if (namedVariables != null) 'namedVariables': namedVariables,
        if (presentationHint != null) 'presentationHint': presentationHint,
        if (type != null) 'type': type,
        'value': value,
        if (variablesReference != null)
          'variablesReference': variablesReference,
      };
}

class SetFunctionBreakpointsResponseBody {
  /// Information about the breakpoints. The array elements correspond to the
  /// elements of the 'breakpoints' array.
  final List<Breakpoint> breakpoints;

  static SetFunctionBreakpointsResponseBody fromJson(
          Map<String, Object?> obj) =>
      SetFunctionBreakpointsResponseBody.fromMap(obj);

  SetFunctionBreakpointsResponseBody({
    required this.breakpoints,
  });

  SetFunctionBreakpointsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) => Breakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !Breakpoint.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

class SetInstructionBreakpointsResponseBody {
  /// Information about the breakpoints. The array elements correspond to the
  /// elements of the 'breakpoints' array.
  final List<Breakpoint> breakpoints;

  static SetInstructionBreakpointsResponseBody fromJson(
          Map<String, Object?> obj) =>
      SetInstructionBreakpointsResponseBody.fromMap(obj);

  SetInstructionBreakpointsResponseBody({
    required this.breakpoints,
  });

  SetInstructionBreakpointsResponseBody.fromMap(Map<String, Object?> obj)
      : breakpoints = (obj['breakpoints'] as List)
            .map((item) => Breakpoint.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['breakpoints'] is! List ||
        (obj['breakpoints'].any((item) => !Breakpoint.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'breakpoints': breakpoints,
      };
}

class SetVariableResponseBody {
  /// The number of indexed child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? indexedVariables;

  /// The number of named child variables.
  /// The client can use this optional information to present the variables in a
  /// paged UI and fetch them in chunks.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? namedVariables;

  /// The type of the new value. Typically shown in the UI when hovering over
  /// the value.
  final String? type;

  /// The new value of the variable.
  final String value;

  /// If variablesReference is > 0, the new value is structured and its children
  /// can be retrieved by passing variablesReference to the VariablesRequest.
  /// The value should be less than or equal to 2147483647 (2^31-1).
  final int? variablesReference;

  static SetVariableResponseBody fromJson(Map<String, Object?> obj) =>
      SetVariableResponseBody.fromMap(obj);

  SetVariableResponseBody({
    this.indexedVariables,
    this.namedVariables,
    this.type,
    required this.value,
    this.variablesReference,
  });

  SetVariableResponseBody.fromMap(Map<String, Object?> obj)
      : indexedVariables = obj['indexedVariables'] as int?,
        namedVariables = obj['namedVariables'] as int?,
        type = obj['type'] as String?,
        value = obj['value'] as String,
        variablesReference = obj['variablesReference'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['indexedVariables'] is! int?) {
      return false;
    }
    if (obj['namedVariables'] is! int?) {
      return false;
    }
    if (obj['type'] is! String?) {
      return false;
    }
    if (obj['value'] is! String) {
      return false;
    }
    if (obj['variablesReference'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        if (indexedVariables != null) 'indexedVariables': indexedVariables,
        if (namedVariables != null) 'namedVariables': namedVariables,
        if (type != null) 'type': type,
        'value': value,
        if (variablesReference != null)
          'variablesReference': variablesReference,
      };
}

class SourceResponseBody {
  /// Content of the source reference.
  final String content;

  /// Optional content type (mime type) of the source.
  final String? mimeType;

  static SourceResponseBody fromJson(Map<String, Object?> obj) =>
      SourceResponseBody.fromMap(obj);

  SourceResponseBody({
    required this.content,
    this.mimeType,
  });

  SourceResponseBody.fromMap(Map<String, Object?> obj)
      : content = obj['content'] as String,
        mimeType = obj['mimeType'] as String?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['content'] is! String) {
      return false;
    }
    if (obj['mimeType'] is! String?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'content': content,
        if (mimeType != null) 'mimeType': mimeType,
      };
}

class StackTraceResponseBody {
  /// The frames of the stackframe. If the array has length zero, there are no
  /// stackframes available.
  /// This means that there is no location information available.
  final List<StackFrame> stackFrames;

  /// The total number of frames available in the stack. If omitted or if
  /// totalFrames is larger than the available frames, a client is expected to
  /// request frames until a request returns less frames than requested (which
  /// indicates the end of the stack). Returning monotonically increasing
  /// totalFrames values for subsequent requests can be used to enforce paging
  /// in the client.
  final int? totalFrames;

  static StackTraceResponseBody fromJson(Map<String, Object?> obj) =>
      StackTraceResponseBody.fromMap(obj);

  StackTraceResponseBody({
    required this.stackFrames,
    this.totalFrames,
  });

  StackTraceResponseBody.fromMap(Map<String, Object?> obj)
      : stackFrames = (obj['stackFrames'] as List)
            .map((item) => StackFrame.fromJson(item as Map<String, Object?>))
            .toList(),
        totalFrames = obj['totalFrames'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['stackFrames'] is! List ||
        (obj['stackFrames'].any((item) => !StackFrame.canParse(item))))) {
      return false;
    }
    if (obj['totalFrames'] is! int?) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'stackFrames': stackFrames,
        if (totalFrames != null) 'totalFrames': totalFrames,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class StepBackResponseBody {
  static StepBackResponseBody fromJson(Map<String, Object?> obj) =>
      StepBackResponseBody.fromMap(obj);

  StepBackResponseBody();

  StepBackResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

/// Contains request result if success is true and optional error details if
/// success is false.
class StepInResponseBody {
  static StepInResponseBody fromJson(Map<String, Object?> obj) =>
      StepInResponseBody.fromMap(obj);

  StepInResponseBody();

  StepInResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class StepInTargetsResponseBody {
  /// The possible stepIn targets of the specified source location.
  final List<StepInTarget> targets;

  static StepInTargetsResponseBody fromJson(Map<String, Object?> obj) =>
      StepInTargetsResponseBody.fromMap(obj);

  StepInTargetsResponseBody({
    required this.targets,
  });

  StepInTargetsResponseBody.fromMap(Map<String, Object?> obj)
      : targets = (obj['targets'] as List)
            .map((item) => StepInTarget.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['targets'] is! List ||
        (obj['targets'].any((item) => !StepInTarget.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'targets': targets,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class StepOutResponseBody {
  static StepOutResponseBody fromJson(Map<String, Object?> obj) =>
      StepOutResponseBody.fromMap(obj);

  StepOutResponseBody();

  StepOutResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class StoppedEventBody extends EventBody {
  /// If 'allThreadsStopped' is true, a debug adapter can announce that all
  /// threads have stopped.
  /// - The client should use this information to enable that all threads can be expanded to access their stacktraces.
  /// - If the attribute is missing or false, only the thread with the given threadId can be expanded.
  final bool? allThreadsStopped;

  /// The full reason for the event, e.g. 'Paused on exception'. This string is
  /// shown in the UI as is and must be translated.
  final String? description;

  /// Ids of the breakpoints that triggered the event. In most cases there will
  /// be only a single breakpoint but here are some examples for multiple
  /// breakpoints:
  /// - Different types of breakpoints map to the same location.
  /// - Multiple source breakpoints get collapsed to the same instruction by the compiler/runtime.
  /// - Multiple function breakpoints with different function names map to the same location.
  final List<int>? hitBreakpointIds;

  /// A value of true hints to the frontend that this event should not change
  /// the focus.
  final bool? preserveFocusHint;

  /// The reason for the event.
  /// For backward compatibility this string is shown in the UI if the
  /// 'description' attribute is missing (but it must not be translated).
  final String reason;

  /// Additional information. E.g. if reason is 'exception', text contains the
  /// exception name. This string is shown in the UI.
  final String? text;

  /// The thread which was stopped.
  final int? threadId;

  static StoppedEventBody fromJson(Map<String, Object?> obj) =>
      StoppedEventBody.fromMap(obj);

  StoppedEventBody({
    this.allThreadsStopped,
    this.description,
    this.hitBreakpointIds,
    this.preserveFocusHint,
    required this.reason,
    this.text,
    this.threadId,
  });

  StoppedEventBody.fromMap(Map<String, Object?> obj)
      : allThreadsStopped = obj['allThreadsStopped'] as bool?,
        description = obj['description'] as String?,
        hitBreakpointIds = (obj['hitBreakpointIds'] as List?)
            ?.map((item) => item as int)
            .toList(),
        preserveFocusHint = obj['preserveFocusHint'] as bool?,
        reason = obj['reason'] as String,
        text = obj['text'] as String?,
        threadId = obj['threadId'] as int?;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['allThreadsStopped'] is! bool?) {
      return false;
    }
    if (obj['description'] is! String?) {
      return false;
    }
    if ((obj['hitBreakpointIds'] is! List ||
        (obj['hitBreakpointIds'].any((item) => item is! int)))) {
      return false;
    }
    if (obj['preserveFocusHint'] is! bool?) {
      return false;
    }
    if (obj['reason'] is! String) {
      return false;
    }
    if (obj['text'] is! String?) {
      return false;
    }
    if (obj['threadId'] is! int?) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (allThreadsStopped != null) 'allThreadsStopped': allThreadsStopped,
        if (description != null) 'description': description,
        if (hitBreakpointIds != null) 'hitBreakpointIds': hitBreakpointIds,
        if (preserveFocusHint != null) 'preserveFocusHint': preserveFocusHint,
        'reason': reason,
        if (text != null) 'text': text,
        if (threadId != null) 'threadId': threadId,
      };
}

/// Contains request result if success is true and optional error details if
/// success is false.
class TerminateResponseBody {
  static TerminateResponseBody fromJson(Map<String, Object?> obj) =>
      TerminateResponseBody.fromMap(obj);

  TerminateResponseBody();

  TerminateResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

/// Contains request result if success is true and optional error details if
/// success is false.
class TerminateThreadsResponseBody {
  static TerminateThreadsResponseBody fromJson(Map<String, Object?> obj) =>
      TerminateThreadsResponseBody.fromMap(obj);

  TerminateThreadsResponseBody();

  TerminateThreadsResponseBody.fromMap(Map<String, Object?> obj);

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {};
}

class TerminatedEventBody extends EventBody {
  /// A debug adapter may set 'restart' to true (or to an arbitrary object) to
  /// request that the front end restarts the session.
  /// The value is not interpreted by the client and passed unmodified as an
  /// attribute '__restart' to the 'launch' and 'attach' requests.
  final Object? restart;

  static TerminatedEventBody fromJson(Map<String, Object?> obj) =>
      TerminatedEventBody.fromMap(obj);

  TerminatedEventBody({
    this.restart,
  });

  TerminatedEventBody.fromMap(Map<String, Object?> obj)
      : restart = obj['restart'];

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        if (restart != null) 'restart': restart,
      };
}

class ThreadEventBody extends EventBody {
  /// The reason for the event.
  final String reason;

  /// The identifier of the thread.
  final int threadId;

  static ThreadEventBody fromJson(Map<String, Object?> obj) =>
      ThreadEventBody.fromMap(obj);

  ThreadEventBody({
    required this.reason,
    required this.threadId,
  });

  ThreadEventBody.fromMap(Map<String, Object?> obj)
      : reason = obj['reason'] as String,
        threadId = obj['threadId'] as int;

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if (obj['reason'] is! String) {
      return false;
    }
    if (obj['threadId'] is! int) {
      return false;
    }
    return EventBody.canParse(obj);
  }

  Map<String, Object?> toJson() => {
        'reason': reason,
        'threadId': threadId,
      };
}

class ThreadsResponseBody {
  /// All threads.
  final List<Thread> threads;

  static ThreadsResponseBody fromJson(Map<String, Object?> obj) =>
      ThreadsResponseBody.fromMap(obj);

  ThreadsResponseBody({
    required this.threads,
  });

  ThreadsResponseBody.fromMap(Map<String, Object?> obj)
      : threads = (obj['threads'] as List)
            .map((item) => Thread.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['threads'] is! List ||
        (obj['threads'].any((item) => !Thread.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'threads': threads,
      };
}

class VariablesResponseBody {
  /// All (or a range) of variables for the given variable reference.
  final List<Variable> variables;

  static VariablesResponseBody fromJson(Map<String, Object?> obj) =>
      VariablesResponseBody.fromMap(obj);

  VariablesResponseBody({
    required this.variables,
  });

  VariablesResponseBody.fromMap(Map<String, Object?> obj)
      : variables = (obj['variables'] as List)
            .map((item) => Variable.fromJson(item as Map<String, Object?>))
            .toList();

  static bool canParse(Object? obj) {
    if (obj is! Map<String, dynamic>) {
      return false;
    }
    if ((obj['variables'] is! List ||
        (obj['variables'].any((item) => !Variable.canParse(item))))) {
      return false;
    }
    return true;
  }

  Map<String, Object?> toJson() => {
        'variables': variables,
      };
}

const eventTypes = {
  BreakpointEventBody: 'breakpoint',
  CapabilitiesEventBody: 'capabilities',
  ContinuedEventBody: 'continued',
  ExitedEventBody: 'exited',
  InitializedEventBody: 'initialized',
  InvalidatedEventBody: 'invalidated',
  LoadedSourceEventBody: 'loadedSource',
  ModuleEventBody: 'module',
  OutputEventBody: 'output',
  ProcessEventBody: 'process',
  ProgressEndEventBody: 'progressEnd',
  ProgressStartEventBody: 'progressStart',
  ProgressUpdateEventBody: 'progressUpdate',
  StoppedEventBody: 'stopped',
  TerminatedEventBody: 'terminated',
  ThreadEventBody: 'thread',
};

const commandTypes = {
  AttachRequestArguments: 'attach',
  BreakpointLocationsArguments: 'breakpointLocations',
  CancelArguments: 'cancel',
  CompletionsArguments: 'completions',
  ConfigurationDoneArguments: 'configurationDone',
  ContinueArguments: 'continue',
  DataBreakpointInfoArguments: 'dataBreakpointInfo',
  DisassembleArguments: 'disassemble',
  DisconnectArguments: 'disconnect',
  EvaluateArguments: 'evaluate',
  ExceptionInfoArguments: 'exceptionInfo',
  GotoArguments: 'goto',
  GotoTargetsArguments: 'gotoTargets',
  InitializeRequestArguments: 'initialize',
  LaunchRequestArguments: 'launch',
  LoadedSourcesArguments: 'loadedSources',
  ModulesArguments: 'modules',
  NextArguments: 'next',
  PauseArguments: 'pause',
  ReadMemoryArguments: 'readMemory',
  RestartFrameArguments: 'restartFrame',
  RestartArguments: 'restart',
  ReverseContinueArguments: 'reverseContinue',
  RunInTerminalRequestArguments: 'runInTerminal',
  ScopesArguments: 'scopes',
  SetBreakpointsArguments: 'setBreakpoints',
  SetDataBreakpointsArguments: 'setDataBreakpoints',
  SetExceptionBreakpointsArguments: 'setExceptionBreakpoints',
  SetExpressionArguments: 'setExpression',
  SetFunctionBreakpointsArguments: 'setFunctionBreakpoints',
  SetInstructionBreakpointsArguments: 'setInstructionBreakpoints',
  SetVariableArguments: 'setVariable',
  SourceArguments: 'source',
  StackTraceArguments: 'stackTrace',
  StepBackArguments: 'stepBack',
  StepInArguments: 'stepIn',
  StepInTargetsArguments: 'stepInTargets',
  StepOutArguments: 'stepOut',
  TerminateArguments: 'terminate',
  TerminateThreadsArguments: 'terminateThreads',
  VariablesArguments: 'variables',
};
