// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'devtools_request.dart';

// **************************************************************************
// BuiltValueGenerator
// **************************************************************************

Serializer<DevToolsRequest> _$devToolsRequestSerializer =
    _$DevToolsRequestSerializer();
Serializer<DevToolsResponse> _$devToolsResponseSerializer =
    _$DevToolsResponseSerializer();

class _$DevToolsRequestSerializer
    implements StructuredSerializer<DevToolsRequest> {
  @override
  final Iterable<Type> types = const [DevToolsRequest, _$DevToolsRequest];
  @override
  final String wireName = 'DevToolsRequest';

  @override
  Iterable<Object?> serialize(
    Serializers serializers,
    DevToolsRequest object, {
    FullType specifiedType = FullType.unspecified,
  }) {
    final result = <Object?>[
      'appId',
      serializers.serialize(
        object.appId,
        specifiedType: const FullType(String),
      ),
      'instanceId',
      serializers.serialize(
        object.instanceId,
        specifiedType: const FullType(String),
      ),
    ];
    Object? value;
    value = object.contextId;
    if (value != null) {
      result
        ..add('contextId')
        ..add(serializers.serialize(value, specifiedType: const FullType(int)));
    }
    value = object.tabUrl;
    if (value != null) {
      result
        ..add('tabUrl')
        ..add(
          serializers.serialize(value, specifiedType: const FullType(String)),
        );
    }
    value = object.uriOnly;
    if (value != null) {
      result
        ..add('uriOnly')
        ..add(
          serializers.serialize(value, specifiedType: const FullType(bool)),
        );
    }
    value = object.client;
    if (value != null) {
      result
        ..add('client')
        ..add(
          serializers.serialize(value, specifiedType: const FullType(String)),
        );
    }
    return result;
  }

  @override
  DevToolsRequest deserialize(
    Serializers serializers,
    Iterable<Object?> serialized, {
    FullType specifiedType = FullType.unspecified,
  }) {
    final result = DevToolsRequestBuilder();

    final iterator = serialized.iterator;
    while (iterator.moveNext()) {
      final key = iterator.current! as String;
      iterator.moveNext();
      final Object? value = iterator.current;
      switch (key) {
        case 'appId':
          result.appId =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(String),
                  )!
                  as String;
          break;
        case 'instanceId':
          result.instanceId =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(String),
                  )!
                  as String;
          break;
        case 'contextId':
          result.contextId =
              serializers.deserialize(value, specifiedType: const FullType(int))
                  as int?;
          break;
        case 'tabUrl':
          result.tabUrl =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(String),
                  )
                  as String?;
          break;
        case 'uriOnly':
          result.uriOnly =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(bool),
                  )
                  as bool?;
          break;
        case 'client':
          result.client =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(String),
                  )
                  as String?;
          break;
      }
    }

    return result.build();
  }
}

class _$DevToolsResponseSerializer
    implements StructuredSerializer<DevToolsResponse> {
  @override
  final Iterable<Type> types = const [DevToolsResponse, _$DevToolsResponse];
  @override
  final String wireName = 'DevToolsResponse';

  @override
  Iterable<Object?> serialize(
    Serializers serializers,
    DevToolsResponse object, {
    FullType specifiedType = FullType.unspecified,
  }) {
    final result = <Object?>[
      'success',
      serializers.serialize(
        object.success,
        specifiedType: const FullType(bool),
      ),
      'promptExtension',
      serializers.serialize(
        object.promptExtension,
        specifiedType: const FullType(bool),
      ),
    ];
    Object? value;
    value = object.error;
    if (value != null) {
      result
        ..add('error')
        ..add(
          serializers.serialize(value, specifiedType: const FullType(String)),
        );
    }
    return result;
  }

  @override
  DevToolsResponse deserialize(
    Serializers serializers,
    Iterable<Object?> serialized, {
    FullType specifiedType = FullType.unspecified,
  }) {
    final result = DevToolsResponseBuilder();

    final iterator = serialized.iterator;
    while (iterator.moveNext()) {
      final key = iterator.current! as String;
      iterator.moveNext();
      final Object? value = iterator.current;
      switch (key) {
        case 'success':
          result.success =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(bool),
                  )!
                  as bool;
          break;
        case 'promptExtension':
          result.promptExtension =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(bool),
                  )!
                  as bool;
          break;
        case 'error':
          result.error =
              serializers.deserialize(
                    value,
                    specifiedType: const FullType(String),
                  )
                  as String?;
          break;
      }
    }

    return result.build();
  }
}

class _$DevToolsRequest extends DevToolsRequest {
  @override
  final String appId;
  @override
  final String instanceId;
  @override
  final int? contextId;
  @override
  final String? tabUrl;
  @override
  final bool? uriOnly;
  @override
  final String? client;

  factory _$DevToolsRequest([void Function(DevToolsRequestBuilder)? updates]) =>
      (DevToolsRequestBuilder()..update(updates))._build();

  _$DevToolsRequest._({
    required this.appId,
    required this.instanceId,
    this.contextId,
    this.tabUrl,
    this.uriOnly,
    this.client,
  }) : super._();
  @override
  DevToolsRequest rebuild(void Function(DevToolsRequestBuilder) updates) =>
      (toBuilder()..update(updates)).build();

  @override
  DevToolsRequestBuilder toBuilder() => DevToolsRequestBuilder()..replace(this);

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    return other is DevToolsRequest &&
        appId == other.appId &&
        instanceId == other.instanceId &&
        contextId == other.contextId &&
        tabUrl == other.tabUrl &&
        uriOnly == other.uriOnly &&
        client == other.client;
  }

  @override
  int get hashCode {
    var _$hash = 0;
    _$hash = $jc(_$hash, appId.hashCode);
    _$hash = $jc(_$hash, instanceId.hashCode);
    _$hash = $jc(_$hash, contextId.hashCode);
    _$hash = $jc(_$hash, tabUrl.hashCode);
    _$hash = $jc(_$hash, uriOnly.hashCode);
    _$hash = $jc(_$hash, client.hashCode);
    _$hash = $jf(_$hash);
    return _$hash;
  }

  @override
  String toString() {
    return (newBuiltValueToStringHelper(r'DevToolsRequest')
          ..add('appId', appId)
          ..add('instanceId', instanceId)
          ..add('contextId', contextId)
          ..add('tabUrl', tabUrl)
          ..add('uriOnly', uriOnly)
          ..add('client', client))
        .toString();
  }
}

class DevToolsRequestBuilder
    implements Builder<DevToolsRequest, DevToolsRequestBuilder> {
  _$DevToolsRequest? _$v;

  String? _appId;
  String? get appId => _$this._appId;
  set appId(String? appId) => _$this._appId = appId;

  String? _instanceId;
  String? get instanceId => _$this._instanceId;
  set instanceId(String? instanceId) => _$this._instanceId = instanceId;

  int? _contextId;
  int? get contextId => _$this._contextId;
  set contextId(int? contextId) => _$this._contextId = contextId;

  String? _tabUrl;
  String? get tabUrl => _$this._tabUrl;
  set tabUrl(String? tabUrl) => _$this._tabUrl = tabUrl;

  bool? _uriOnly;
  bool? get uriOnly => _$this._uriOnly;
  set uriOnly(bool? uriOnly) => _$this._uriOnly = uriOnly;

  String? _client;
  String? get client => _$this._client;
  set client(String? client) => _$this._client = client;

  DevToolsRequestBuilder();

  DevToolsRequestBuilder get _$this {
    final $v = _$v;
    if ($v != null) {
      _appId = $v.appId;
      _instanceId = $v.instanceId;
      _contextId = $v.contextId;
      _tabUrl = $v.tabUrl;
      _uriOnly = $v.uriOnly;
      _client = $v.client;
      _$v = null;
    }
    return this;
  }

  @override
  void replace(DevToolsRequest other) {
    _$v = other as _$DevToolsRequest;
  }

  @override
  void update(void Function(DevToolsRequestBuilder)? updates) {
    if (updates != null) updates(this);
  }

  @override
  DevToolsRequest build() => _build();

  _$DevToolsRequest _build() {
    final _$result =
        _$v ??
        _$DevToolsRequest._(
          appId: BuiltValueNullFieldError.checkNotNull(
            appId,
            r'DevToolsRequest',
            'appId',
          ),
          instanceId: BuiltValueNullFieldError.checkNotNull(
            instanceId,
            r'DevToolsRequest',
            'instanceId',
          ),
          contextId: contextId,
          tabUrl: tabUrl,
          uriOnly: uriOnly,
          client: client,
        );
    replace(_$result);
    return _$result;
  }
}

class _$DevToolsResponse extends DevToolsResponse {
  @override
  final bool success;
  @override
  final bool promptExtension;
  @override
  final String? error;

  factory _$DevToolsResponse([
    void Function(DevToolsResponseBuilder)? updates,
  ]) => (DevToolsResponseBuilder()..update(updates))._build();

  _$DevToolsResponse._({
    required this.success,
    required this.promptExtension,
    this.error,
  }) : super._();
  @override
  DevToolsResponse rebuild(void Function(DevToolsResponseBuilder) updates) =>
      (toBuilder()..update(updates)).build();

  @override
  DevToolsResponseBuilder toBuilder() =>
      DevToolsResponseBuilder()..replace(this);

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    return other is DevToolsResponse &&
        success == other.success &&
        promptExtension == other.promptExtension &&
        error == other.error;
  }

  @override
  int get hashCode {
    var _$hash = 0;
    _$hash = $jc(_$hash, success.hashCode);
    _$hash = $jc(_$hash, promptExtension.hashCode);
    _$hash = $jc(_$hash, error.hashCode);
    _$hash = $jf(_$hash);
    return _$hash;
  }

  @override
  String toString() {
    return (newBuiltValueToStringHelper(r'DevToolsResponse')
          ..add('success', success)
          ..add('promptExtension', promptExtension)
          ..add('error', error))
        .toString();
  }
}

class DevToolsResponseBuilder
    implements Builder<DevToolsResponse, DevToolsResponseBuilder> {
  _$DevToolsResponse? _$v;

  bool? _success;
  bool? get success => _$this._success;
  set success(bool? success) => _$this._success = success;

  bool? _promptExtension;
  bool? get promptExtension => _$this._promptExtension;
  set promptExtension(bool? promptExtension) =>
      _$this._promptExtension = promptExtension;

  String? _error;
  String? get error => _$this._error;
  set error(String? error) => _$this._error = error;

  DevToolsResponseBuilder();

  DevToolsResponseBuilder get _$this {
    final $v = _$v;
    if ($v != null) {
      _success = $v.success;
      _promptExtension = $v.promptExtension;
      _error = $v.error;
      _$v = null;
    }
    return this;
  }

  @override
  void replace(DevToolsResponse other) {
    _$v = other as _$DevToolsResponse;
  }

  @override
  void update(void Function(DevToolsResponseBuilder)? updates) {
    if (updates != null) updates(this);
  }

  @override
  DevToolsResponse build() => _build();

  _$DevToolsResponse _build() {
    final _$result =
        _$v ??
        _$DevToolsResponse._(
          success: BuiltValueNullFieldError.checkNotNull(
            success,
            r'DevToolsResponse',
            'success',
          ),
          promptExtension: BuiltValueNullFieldError.checkNotNull(
            promptExtension,
            r'DevToolsResponse',
            'promptExtension',
          ),
          error: error,
        );
    replace(_$result);
    return _$result;
  }
}

// ignore_for_file: deprecated_member_use_from_same_package,type=lint
