// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v4.2.13), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;

import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';

/// Mirror of NSKeyValueObservingOptions.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvalueobservingoptions?language=objc.
enum NSKeyValueObservingOptionsEnum {
  newValue,
  oldValue,
  initialValue,
  priorNotification,
}

/// Mirror of NSKeyValueChange.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechange?language=objc.
enum NSKeyValueChangeEnum {
  setting,
  insertion,
  removal,
  replacement,
}

/// Mirror of NSKeyValueChangeKey.
///
/// See https://developer.apple.com/documentation/foundation/nskeyvaluechangekey?language=objc.
enum NSKeyValueChangeKeyEnum {
  indexes,
  kind,
  newValue,
  notificationIsPrior,
  oldValue,
}

/// Mirror of WKUserScriptInjectionTime.
///
/// See https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime?language=objc.
enum WKUserScriptInjectionTimeEnum {
  atDocumentStart,
  atDocumentEnd,
}

/// Mirror of WKAudiovisualMediaTypes.
///
/// See [WKAudiovisualMediaTypes](https://developer.apple.com/documentation/webkit/wkaudiovisualmediatypes?language=objc).
enum WKAudiovisualMediaTypeEnum {
  none,
  audio,
  video,
  all,
}

/// Mirror of WKWebsiteDataTypes.
///
/// See https://developer.apple.com/documentation/webkit/wkwebsitedatarecord/data_store_record_types?language=objc.
enum WKWebsiteDataTypeEnum {
  cookies,
  memoryCache,
  diskCache,
  offlineWebApplicationCache,
  localStorage,
  sessionStorage,
  webSQLDatabases,
  indexedDBDatabases,
}

/// Mirror of WKNavigationActionPolicy.
///
/// See https://developer.apple.com/documentation/webkit/wknavigationactionpolicy?language=objc.
enum WKNavigationActionPolicyEnum {
  allow,
  cancel,
}

/// Mirror of NSHTTPCookiePropertyKey.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookiepropertykey.
enum NSHttpCookiePropertyKeyEnum {
  comment,
  commentUrl,
  discard,
  domain,
  expires,
  maximumAge,
  name,
  originUrl,
  path,
  port,
  sameSitePolicy,
  secure,
  value,
  version,
}

/// An object that contains information about an action that causes navigation
/// to occur.
///
/// Wraps [WKNavigationType](https://developer.apple.com/documentation/webkit/wknavigationaction?language=objc).
enum WKNavigationType {
  /// A link activation.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypelinkactivated?language=objc.
  linkActivated,

  /// A request to submit a form.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypeformsubmitted?language=objc.
  submitted,

  /// A request for the frame’s next or previous item.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypebackforward?language=objc.
  backForward,

  /// A request to reload the webpage.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypereload?language=objc.
  reload,

  /// A request to resubmit a form.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypeformresubmitted?language=objc.
  formResubmitted,

  /// A navigation request that originates for some other reason.
  ///
  /// See https://developer.apple.com/documentation/webkit/wknavigationtype/wknavigationtypeother?language=objc.
  other,
}

class NSKeyValueObservingOptionsEnumData {
  NSKeyValueObservingOptionsEnumData({
    required this.value,
  });

  NSKeyValueObservingOptionsEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static NSKeyValueObservingOptionsEnumData decode(Object result) {
    result as List<Object?>;
    return NSKeyValueObservingOptionsEnumData(
      value: NSKeyValueObservingOptionsEnum.values[result[0]! as int],
    );
  }
}

class NSKeyValueChangeKeyEnumData {
  NSKeyValueChangeKeyEnumData({
    required this.value,
  });

  NSKeyValueChangeKeyEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static NSKeyValueChangeKeyEnumData decode(Object result) {
    result as List<Object?>;
    return NSKeyValueChangeKeyEnumData(
      value: NSKeyValueChangeKeyEnum.values[result[0]! as int],
    );
  }
}

class WKUserScriptInjectionTimeEnumData {
  WKUserScriptInjectionTimeEnumData({
    required this.value,
  });

  WKUserScriptInjectionTimeEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static WKUserScriptInjectionTimeEnumData decode(Object result) {
    result as List<Object?>;
    return WKUserScriptInjectionTimeEnumData(
      value: WKUserScriptInjectionTimeEnum.values[result[0]! as int],
    );
  }
}

class WKAudiovisualMediaTypeEnumData {
  WKAudiovisualMediaTypeEnumData({
    required this.value,
  });

  WKAudiovisualMediaTypeEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static WKAudiovisualMediaTypeEnumData decode(Object result) {
    result as List<Object?>;
    return WKAudiovisualMediaTypeEnumData(
      value: WKAudiovisualMediaTypeEnum.values[result[0]! as int],
    );
  }
}

class WKWebsiteDataTypeEnumData {
  WKWebsiteDataTypeEnumData({
    required this.value,
  });

  WKWebsiteDataTypeEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static WKWebsiteDataTypeEnumData decode(Object result) {
    result as List<Object?>;
    return WKWebsiteDataTypeEnumData(
      value: WKWebsiteDataTypeEnum.values[result[0]! as int],
    );
  }
}

class WKNavigationActionPolicyEnumData {
  WKNavigationActionPolicyEnumData({
    required this.value,
  });

  WKNavigationActionPolicyEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static WKNavigationActionPolicyEnumData decode(Object result) {
    result as List<Object?>;
    return WKNavigationActionPolicyEnumData(
      value: WKNavigationActionPolicyEnum.values[result[0]! as int],
    );
  }
}

class NSHttpCookiePropertyKeyEnumData {
  NSHttpCookiePropertyKeyEnumData({
    required this.value,
  });

  NSHttpCookiePropertyKeyEnum value;

  Object encode() {
    return <Object?>[
      value.index,
    ];
  }

  static NSHttpCookiePropertyKeyEnumData decode(Object result) {
    result as List<Object?>;
    return NSHttpCookiePropertyKeyEnumData(
      value: NSHttpCookiePropertyKeyEnum.values[result[0]! as int],
    );
  }
}

/// Mirror of NSURLRequest.
///
/// See https://developer.apple.com/documentation/foundation/nsurlrequest?language=objc.
class NSUrlRequestData {
  NSUrlRequestData({
    required this.url,
    this.httpMethod,
    this.httpBody,
    required this.allHttpHeaderFields,
  });

  String url;

  String? httpMethod;

  Uint8List? httpBody;

  Map<String?, String?> allHttpHeaderFields;

  Object encode() {
    return <Object?>[
      url,
      httpMethod,
      httpBody,
      allHttpHeaderFields,
    ];
  }

  static NSUrlRequestData decode(Object result) {
    result as List<Object?>;
    return NSUrlRequestData(
      url: result[0]! as String,
      httpMethod: result[1] as String?,
      httpBody: result[2] as Uint8List?,
      allHttpHeaderFields:
          (result[3] as Map<Object?, Object?>?)!.cast<String?, String?>(),
    );
  }
}

/// Mirror of WKUserScript.
///
/// See https://developer.apple.com/documentation/webkit/wkuserscript?language=objc.
class WKUserScriptData {
  WKUserScriptData({
    required this.source,
    this.injectionTime,
    required this.isMainFrameOnly,
  });

  String source;

  WKUserScriptInjectionTimeEnumData? injectionTime;

  bool isMainFrameOnly;

  Object encode() {
    return <Object?>[
      source,
      injectionTime?.encode(),
      isMainFrameOnly,
    ];
  }

  static WKUserScriptData decode(Object result) {
    result as List<Object?>;
    return WKUserScriptData(
      source: result[0]! as String,
      injectionTime: result[1] != null
          ? WKUserScriptInjectionTimeEnumData.decode(
              result[1]! as List<Object?>)
          : null,
      isMainFrameOnly: result[2]! as bool,
    );
  }
}

/// Mirror of WKNavigationAction.
///
/// See https://developer.apple.com/documentation/webkit/wknavigationaction.
class WKNavigationActionData {
  WKNavigationActionData({
    required this.request,
    required this.targetFrame,
    required this.navigationType,
  });

  NSUrlRequestData request;

  WKFrameInfoData targetFrame;

  WKNavigationType navigationType;

  Object encode() {
    return <Object?>[
      request.encode(),
      targetFrame.encode(),
      navigationType.index,
    ];
  }

  static WKNavigationActionData decode(Object result) {
    result as List<Object?>;
    return WKNavigationActionData(
      request: NSUrlRequestData.decode(result[0]! as List<Object?>),
      targetFrame: WKFrameInfoData.decode(result[1]! as List<Object?>),
      navigationType: WKNavigationType.values[result[2]! as int],
    );
  }
}

/// Mirror of WKFrameInfo.
///
/// See https://developer.apple.com/documentation/webkit/wkframeinfo?language=objc.
class WKFrameInfoData {
  WKFrameInfoData({
    required this.isMainFrame,
  });

  bool isMainFrame;

  Object encode() {
    return <Object?>[
      isMainFrame,
    ];
  }

  static WKFrameInfoData decode(Object result) {
    result as List<Object?>;
    return WKFrameInfoData(
      isMainFrame: result[0]! as bool,
    );
  }
}

/// Mirror of NSError.
///
/// See https://developer.apple.com/documentation/foundation/nserror?language=objc.
class NSErrorData {
  NSErrorData({
    required this.code,
    required this.domain,
    required this.localizedDescription,
  });

  int code;

  String domain;

  String localizedDescription;

  Object encode() {
    return <Object?>[
      code,
      domain,
      localizedDescription,
    ];
  }

  static NSErrorData decode(Object result) {
    result as List<Object?>;
    return NSErrorData(
      code: result[0]! as int,
      domain: result[1]! as String,
      localizedDescription: result[2]! as String,
    );
  }
}

/// Mirror of WKScriptMessage.
///
/// See https://developer.apple.com/documentation/webkit/wkscriptmessage?language=objc.
class WKScriptMessageData {
  WKScriptMessageData({
    required this.name,
    this.body,
  });

  String name;

  Object? body;

  Object encode() {
    return <Object?>[
      name,
      body,
    ];
  }

  static WKScriptMessageData decode(Object result) {
    result as List<Object?>;
    return WKScriptMessageData(
      name: result[0]! as String,
      body: result[1] as Object?,
    );
  }
}

/// Mirror of NSHttpCookieData.
///
/// See https://developer.apple.com/documentation/foundation/nshttpcookie?language=objc.
class NSHttpCookieData {
  NSHttpCookieData({
    required this.propertyKeys,
    required this.propertyValues,
  });

  List<NSHttpCookiePropertyKeyEnumData?> propertyKeys;

  List<Object?> propertyValues;

  Object encode() {
    return <Object?>[
      propertyKeys,
      propertyValues,
    ];
  }

  static NSHttpCookieData decode(Object result) {
    result as List<Object?>;
    return NSHttpCookieData(
      propertyKeys: (result[0] as List<Object?>?)!
          .cast<NSHttpCookiePropertyKeyEnumData?>(),
      propertyValues: (result[1] as List<Object?>?)!.cast<Object?>(),
    );
  }
}

class _WKWebsiteDataStoreHostApiCodec extends StandardMessageCodec {
  const _WKWebsiteDataStoreHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is WKWebsiteDataTypeEnumData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of WKWebsiteDataStore.
///
/// See https://developer.apple.com/documentation/webkit/wkwebsitedatastore?language=objc.
class WKWebsiteDataStoreHostApi {
  /// Constructor for [WKWebsiteDataStoreHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKWebsiteDataStoreHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = _WKWebsiteDataStoreHostApiCodec();

  Future<void> createFromWebViewConfiguration(
      int arg_identifier, int arg_configurationIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_configurationIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> createDefaultDataStore(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createDefaultDataStore',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<bool> removeDataOfTypes(
      int arg_identifier,
      List<WKWebsiteDataTypeEnumData?> arg_dataTypes,
      double arg_modificationTimeInSecondsSinceEpoch) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel.send(<Object?>[
      arg_identifier,
      arg_dataTypes,
      arg_modificationTimeInSecondsSinceEpoch
    ]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else if (replyList[0] == null) {
      throw PlatformException(
        code: 'null-error',
        message: 'Host platform returned null value for non-null return value.',
      );
    } else {
      return (replyList[0] as bool?)!;
    }
  }
}

/// Mirror of UIView.
///
/// See https://developer.apple.com/documentation/uikit/uiview?language=objc.
class UIViewHostApi {
  /// Constructor for [UIViewHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  UIViewHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> setBackgroundColor(int arg_identifier, int? arg_value) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIViewHostApi.setBackgroundColor', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_value]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setOpaque(int arg_identifier, bool arg_opaque) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIViewHostApi.setOpaque', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_opaque]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

/// Mirror of UIScrollView.
///
/// See https://developer.apple.com/documentation/uikit/uiscrollview?language=objc.
class UIScrollViewHostApi {
  /// Constructor for [UIScrollViewHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  UIScrollViewHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> createFromWebView(
      int arg_identifier, int arg_webViewIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier, arg_webViewIdentifier])
            as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<List<double?>> getContentOffset(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIScrollViewHostApi.getContentOffset', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else if (replyList[0] == null) {
      throw PlatformException(
        code: 'null-error',
        message: 'Host platform returned null value for non-null return value.',
      );
    } else {
      return (replyList[0] as List<Object?>?)!.cast<double?>();
    }
  }

  Future<void> scrollBy(int arg_identifier, double arg_x, double arg_y) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIScrollViewHostApi.scrollBy', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_x, arg_y]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setContentOffset(
      int arg_identifier, double arg_x, double arg_y) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_x, arg_y]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

class _WKWebViewConfigurationHostApiCodec extends StandardMessageCodec {
  const _WKWebViewConfigurationHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is WKAudiovisualMediaTypeEnumData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of WKWebViewConfiguration.
///
/// See https://developer.apple.com/documentation/webkit/wkwebviewconfiguration?language=objc.
class WKWebViewConfigurationHostApi {
  /// Constructor for [WKWebViewConfigurationHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKWebViewConfigurationHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec =
      _WKWebViewConfigurationHostApiCodec();

  Future<void> create(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewConfigurationHostApi.create', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> createFromWebView(
      int arg_identifier, int arg_webViewIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier, arg_webViewIdentifier])
            as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setAllowsInlineMediaPlayback(
      int arg_identifier, bool arg_allow) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_allow]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setMediaTypesRequiringUserActionForPlayback(int arg_identifier,
      List<WKAudiovisualMediaTypeEnumData?> arg_types) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_types]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

/// Handles callbacks from an WKWebViewConfiguration instance.
///
/// See https://developer.apple.com/documentation/webkit/wkwebviewconfiguration?language=objc.
abstract class WKWebViewConfigurationFlutterApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void create(int identifier);

  static void setup(WKWebViewConfigurationFlutterApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewConfigurationFlutterApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationFlutterApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationFlutterApi.create was null, expected non-null int.');
          api.create(arg_identifier!);
          return;
        });
      }
    }
  }
}

class _WKUserContentControllerHostApiCodec extends StandardMessageCodec {
  const _WKUserContentControllerHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is WKUserScriptData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is WKUserScriptInjectionTimeEnumData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return WKUserScriptData.decode(readValue(buffer)!);

      case 129:
        return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of WKUserContentController.
///
/// See https://developer.apple.com/documentation/webkit/wkusercontentcontroller?language=objc.
class WKUserContentControllerHostApi {
  /// Constructor for [WKUserContentControllerHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKUserContentControllerHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec =
      _WKUserContentControllerHostApiCodec();

  Future<void> createFromWebViewConfiguration(
      int arg_identifier, int arg_configurationIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_configurationIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> addScriptMessageHandler(
      int arg_identifier, int arg_handlerIdentifier, String arg_name) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_handlerIdentifier, arg_name])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> removeScriptMessageHandler(
      int arg_identifier, String arg_name) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.removeScriptMessageHandler',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_name]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> removeAllScriptMessageHandlers(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllScriptMessageHandlers',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> addUserScript(
      int arg_identifier, WKUserScriptData arg_userScript) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.addUserScript',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_userScript]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> removeAllUserScripts(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllUserScripts',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

/// Mirror of WKUserPreferences.
///
/// See https://developer.apple.com/documentation/webkit/wkpreferences?language=objc.
class WKPreferencesHostApi {
  /// Constructor for [WKPreferencesHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKPreferencesHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> createFromWebViewConfiguration(
      int arg_identifier, int arg_configurationIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_configurationIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setJavaScriptEnabled(
      int arg_identifier, bool arg_enabled) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKPreferencesHostApi.setJavaScriptEnabled', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_enabled]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

/// Mirror of WKScriptMessageHandler.
///
/// See https://developer.apple.com/documentation/webkit/wkscriptmessagehandler?language=objc.
class WKScriptMessageHandlerHostApi {
  /// Constructor for [WKScriptMessageHandlerHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKScriptMessageHandlerHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> create(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKScriptMessageHandlerHostApi.create', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

class _WKScriptMessageHandlerFlutterApiCodec extends StandardMessageCodec {
  const _WKScriptMessageHandlerFlutterApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is WKScriptMessageData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return WKScriptMessageData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Handles callbacks from an WKScriptMessageHandler instance.
///
/// See https://developer.apple.com/documentation/webkit/wkscriptmessagehandler?language=objc.
abstract class WKScriptMessageHandlerFlutterApi {
  static const MessageCodec<Object?> codec =
      _WKScriptMessageHandlerFlutterApiCodec();

  void didReceiveScriptMessage(int identifier,
      int userContentControllerIdentifier, WKScriptMessageData message);

  static void setup(WKScriptMessageHandlerFlutterApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage was null, expected non-null int.');
          final int? arg_userContentControllerIdentifier = (args[1] as int?);
          assert(arg_userContentControllerIdentifier != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage was null, expected non-null int.');
          final WKScriptMessageData? arg_message =
              (args[2] as WKScriptMessageData?);
          assert(arg_message != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage was null, expected non-null WKScriptMessageData.');
          api.didReceiveScriptMessage(arg_identifier!,
              arg_userContentControllerIdentifier!, arg_message!);
          return;
        });
      }
    }
  }
}

/// Mirror of WKNavigationDelegate.
///
/// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc.
class WKNavigationDelegateHostApi {
  /// Constructor for [WKNavigationDelegateHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKNavigationDelegateHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> create(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKNavigationDelegateHostApi.create', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

class _WKNavigationDelegateFlutterApiCodec extends StandardMessageCodec {
  const _WKNavigationDelegateFlutterApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSErrorData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is NSUrlRequestData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is WKFrameInfoData) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionData) {
      buffer.putUint8(131);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionPolicyEnumData) {
      buffer.putUint8(132);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSErrorData.decode(readValue(buffer)!);

      case 129:
        return NSUrlRequestData.decode(readValue(buffer)!);

      case 130:
        return WKFrameInfoData.decode(readValue(buffer)!);

      case 131:
        return WKNavigationActionData.decode(readValue(buffer)!);

      case 132:
        return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Handles callbacks from an WKNavigationDelegate instance.
///
/// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc.
abstract class WKNavigationDelegateFlutterApi {
  static const MessageCodec<Object?> codec =
      _WKNavigationDelegateFlutterApiCodec();

  void didFinishNavigation(int identifier, int webViewIdentifier, String? url);

  void didStartProvisionalNavigation(
      int identifier, int webViewIdentifier, String? url);

  Future<WKNavigationActionPolicyEnumData> decidePolicyForNavigationAction(
      int identifier,
      int webViewIdentifier,
      WKNavigationActionData navigationAction);

  void didFailNavigation(
      int identifier, int webViewIdentifier, NSErrorData error);

  void didFailProvisionalNavigation(
      int identifier, int webViewIdentifier, NSErrorData error);

  void webViewWebContentProcessDidTerminate(
      int identifier, int webViewIdentifier);

  static void setup(WKNavigationDelegateFlutterApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null, expected non-null int.');
          final String? arg_url = (args[2] as String?);
          api.didFinishNavigation(
              arg_identifier!, arg_webViewIdentifier!, arg_url);
          return;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation was null, expected non-null int.');
          final String? arg_url = (args[2] as String?);
          api.didStartProvisionalNavigation(
              arg_identifier!, arg_webViewIdentifier!, arg_url);
          return;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction was null, expected non-null int.');
          final WKNavigationActionData? arg_navigationAction =
              (args[2] as WKNavigationActionData?);
          assert(arg_navigationAction != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction was null, expected non-null WKNavigationActionData.');
          final WKNavigationActionPolicyEnumData output =
              await api.decidePolicyForNavigationAction(arg_identifier!,
                  arg_webViewIdentifier!, arg_navigationAction!);
          return output;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation was null, expected non-null int.');
          final NSErrorData? arg_error = (args[2] as NSErrorData?);
          assert(arg_error != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation was null, expected non-null NSErrorData.');
          api.didFailNavigation(
              arg_identifier!, arg_webViewIdentifier!, arg_error!);
          return;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation was null, expected non-null int.');
          final NSErrorData? arg_error = (args[2] as NSErrorData?);
          assert(arg_error != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation was null, expected non-null NSErrorData.');
          api.didFailProvisionalNavigation(
              arg_identifier!, arg_webViewIdentifier!, arg_error!);
          return;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate was null, expected non-null int.');
          api.webViewWebContentProcessDidTerminate(
              arg_identifier!, arg_webViewIdentifier!);
          return;
        });
      }
    }
  }
}

class _NSObjectHostApiCodec extends StandardMessageCodec {
  const _NSObjectHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSKeyValueObservingOptionsEnumData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSKeyValueObservingOptionsEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of NSObject.
///
/// See https://developer.apple.com/documentation/objectivec/nsobject.
class NSObjectHostApi {
  /// Constructor for [NSObjectHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  NSObjectHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = _NSObjectHostApiCodec();

  Future<void> dispose(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.NSObjectHostApi.dispose', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> addObserver(
      int arg_identifier,
      int arg_observerIdentifier,
      String arg_keyPath,
      List<NSKeyValueObservingOptionsEnumData?> arg_options) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.NSObjectHostApi.addObserver', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel.send(<Object?>[
      arg_identifier,
      arg_observerIdentifier,
      arg_keyPath,
      arg_options
    ]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> removeObserver(int arg_identifier, int arg_observerIdentifier,
      String arg_keyPath) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.NSObjectHostApi.removeObserver', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel.send(
            <Object?>[arg_identifier, arg_observerIdentifier, arg_keyPath])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

class _NSObjectFlutterApiCodec extends StandardMessageCodec {
  const _NSObjectFlutterApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSErrorData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is NSHttpCookieData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is NSHttpCookiePropertyKeyEnumData) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else if (value is NSKeyValueChangeKeyEnumData) {
      buffer.putUint8(131);
      writeValue(buffer, value.encode());
    } else if (value is NSKeyValueObservingOptionsEnumData) {
      buffer.putUint8(132);
      writeValue(buffer, value.encode());
    } else if (value is NSUrlRequestData) {
      buffer.putUint8(133);
      writeValue(buffer, value.encode());
    } else if (value is WKAudiovisualMediaTypeEnumData) {
      buffer.putUint8(134);
      writeValue(buffer, value.encode());
    } else if (value is WKFrameInfoData) {
      buffer.putUint8(135);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionData) {
      buffer.putUint8(136);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionPolicyEnumData) {
      buffer.putUint8(137);
      writeValue(buffer, value.encode());
    } else if (value is WKScriptMessageData) {
      buffer.putUint8(138);
      writeValue(buffer, value.encode());
    } else if (value is WKUserScriptData) {
      buffer.putUint8(139);
      writeValue(buffer, value.encode());
    } else if (value is WKUserScriptInjectionTimeEnumData) {
      buffer.putUint8(140);
      writeValue(buffer, value.encode());
    } else if (value is WKWebsiteDataTypeEnumData) {
      buffer.putUint8(141);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSErrorData.decode(readValue(buffer)!);

      case 129:
        return NSHttpCookieData.decode(readValue(buffer)!);

      case 130:
        return NSHttpCookiePropertyKeyEnumData.decode(readValue(buffer)!);

      case 131:
        return NSKeyValueChangeKeyEnumData.decode(readValue(buffer)!);

      case 132:
        return NSKeyValueObservingOptionsEnumData.decode(readValue(buffer)!);

      case 133:
        return NSUrlRequestData.decode(readValue(buffer)!);

      case 134:
        return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!);

      case 135:
        return WKFrameInfoData.decode(readValue(buffer)!);

      case 136:
        return WKNavigationActionData.decode(readValue(buffer)!);

      case 137:
        return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!);

      case 138:
        return WKScriptMessageData.decode(readValue(buffer)!);

      case 139:
        return WKUserScriptData.decode(readValue(buffer)!);

      case 140:
        return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!);

      case 141:
        return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Handles callbacks from an NSObject instance.
///
/// See https://developer.apple.com/documentation/objectivec/nsobject.
abstract class NSObjectFlutterApi {
  static const MessageCodec<Object?> codec = _NSObjectFlutterApiCodec();

  void observeValue(
      int identifier,
      String keyPath,
      int objectIdentifier,
      List<NSKeyValueChangeKeyEnumData?> changeKeys,
      List<Object?> changeValues);

  void dispose(int identifier);

  static void setup(NSObjectFlutterApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.NSObjectFlutterApi.observeValue', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null int.');
          final String? arg_keyPath = (args[1] as String?);
          assert(arg_keyPath != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null String.');
          final int? arg_objectIdentifier = (args[2] as int?);
          assert(arg_objectIdentifier != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null int.');
          final List<NSKeyValueChangeKeyEnumData?>? arg_changeKeys =
              (args[3] as List<Object?>?)?.cast<NSKeyValueChangeKeyEnumData?>();
          assert(arg_changeKeys != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null List<NSKeyValueChangeKeyEnumData?>.');
          final List<Object?>? arg_changeValues =
              (args[4] as List<Object?>?)?.cast<Object?>();
          assert(arg_changeValues != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null List<Object?>.');
          api.observeValue(arg_identifier!, arg_keyPath!, arg_objectIdentifier!,
              arg_changeKeys!, arg_changeValues!);
          return;
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.NSObjectFlutterApi.dispose', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.dispose was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.NSObjectFlutterApi.dispose was null, expected non-null int.');
          api.dispose(arg_identifier!);
          return;
        });
      }
    }
  }
}

class _WKWebViewHostApiCodec extends StandardMessageCodec {
  const _WKWebViewHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSErrorData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is NSHttpCookieData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is NSHttpCookiePropertyKeyEnumData) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else if (value is NSKeyValueChangeKeyEnumData) {
      buffer.putUint8(131);
      writeValue(buffer, value.encode());
    } else if (value is NSKeyValueObservingOptionsEnumData) {
      buffer.putUint8(132);
      writeValue(buffer, value.encode());
    } else if (value is NSUrlRequestData) {
      buffer.putUint8(133);
      writeValue(buffer, value.encode());
    } else if (value is WKAudiovisualMediaTypeEnumData) {
      buffer.putUint8(134);
      writeValue(buffer, value.encode());
    } else if (value is WKFrameInfoData) {
      buffer.putUint8(135);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionData) {
      buffer.putUint8(136);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionPolicyEnumData) {
      buffer.putUint8(137);
      writeValue(buffer, value.encode());
    } else if (value is WKScriptMessageData) {
      buffer.putUint8(138);
      writeValue(buffer, value.encode());
    } else if (value is WKUserScriptData) {
      buffer.putUint8(139);
      writeValue(buffer, value.encode());
    } else if (value is WKUserScriptInjectionTimeEnumData) {
      buffer.putUint8(140);
      writeValue(buffer, value.encode());
    } else if (value is WKWebsiteDataTypeEnumData) {
      buffer.putUint8(141);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSErrorData.decode(readValue(buffer)!);

      case 129:
        return NSHttpCookieData.decode(readValue(buffer)!);

      case 130:
        return NSHttpCookiePropertyKeyEnumData.decode(readValue(buffer)!);

      case 131:
        return NSKeyValueChangeKeyEnumData.decode(readValue(buffer)!);

      case 132:
        return NSKeyValueObservingOptionsEnumData.decode(readValue(buffer)!);

      case 133:
        return NSUrlRequestData.decode(readValue(buffer)!);

      case 134:
        return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!);

      case 135:
        return WKFrameInfoData.decode(readValue(buffer)!);

      case 136:
        return WKNavigationActionData.decode(readValue(buffer)!);

      case 137:
        return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!);

      case 138:
        return WKScriptMessageData.decode(readValue(buffer)!);

      case 139:
        return WKUserScriptData.decode(readValue(buffer)!);

      case 140:
        return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!);

      case 141:
        return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of WKWebView.
///
/// See https://developer.apple.com/documentation/webkit/wkwebview?language=objc.
class WKWebViewHostApi {
  /// Constructor for [WKWebViewHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKWebViewHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = _WKWebViewHostApiCodec();

  Future<void> create(
      int arg_identifier, int arg_configurationIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.create', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_configurationIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setUIDelegate(
      int arg_identifier, int? arg_uiDelegateIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier, arg_uiDelegateIdentifier])
            as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setNavigationDelegate(
      int arg_identifier, int? arg_navigationDelegateIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_navigationDelegateIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<String?> getUrl(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.getUrl', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return (replyList[0] as String?);
    }
  }

  Future<double> getEstimatedProgress(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.getEstimatedProgress', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else if (replyList[0] == null) {
      throw PlatformException(
        code: 'null-error',
        message: 'Host platform returned null value for non-null return value.',
      );
    } else {
      return (replyList[0] as double?)!;
    }
  }

  Future<void> loadRequest(
      int arg_identifier, NSUrlRequestData arg_request) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.loadRequest', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_request]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> loadHtmlString(
      int arg_identifier, String arg_string, String? arg_baseUrl) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier, arg_string, arg_baseUrl])
            as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> loadFileUrl(
      int arg_identifier, String arg_url, String arg_readAccessUrl) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_url, arg_readAccessUrl])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> loadFlutterAsset(int arg_identifier, String arg_key) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.loadFlutterAsset', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_key]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<bool> canGoBack(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.canGoBack', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else if (replyList[0] == null) {
      throw PlatformException(
        code: 'null-error',
        message: 'Host platform returned null value for non-null return value.',
      );
    } else {
      return (replyList[0] as bool?)!;
    }
  }

  Future<bool> canGoForward(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.canGoForward', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else if (replyList[0] == null) {
      throw PlatformException(
        code: 'null-error',
        message: 'Host platform returned null value for non-null return value.',
      );
    } else {
      return (replyList[0] as bool?)!;
    }
  }

  Future<void> goBack(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.goBack', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> goForward(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.goForward', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> reload(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.reload', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<String?> getTitle(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.getTitle', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return (replyList[0] as String?);
    }
  }

  Future<void> setAllowsBackForwardNavigationGestures(
      int arg_identifier, bool arg_allow) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.setAllowsBackForwardNavigationGestures',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_allow]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setCustomUserAgent(
      int arg_identifier, String? arg_userAgent) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_userAgent]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<Object?> evaluateJavaScript(
      int arg_identifier, String arg_javaScriptString) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKWebViewHostApi.evaluateJavaScript', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier, arg_javaScriptString])
            as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return (replyList[0] as Object?);
    }
  }
}

/// Mirror of WKUIDelegate.
///
/// See https://developer.apple.com/documentation/webkit/wkuidelegate?language=objc.
class WKUIDelegateHostApi {
  /// Constructor for [WKUIDelegateHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKUIDelegateHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = StandardMessageCodec();

  Future<void> create(int arg_identifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKUIDelegateHostApi.create', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList =
        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}

class _WKUIDelegateFlutterApiCodec extends StandardMessageCodec {
  const _WKUIDelegateFlutterApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSUrlRequestData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is WKFrameInfoData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is WKNavigationActionData) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSUrlRequestData.decode(readValue(buffer)!);

      case 129:
        return WKFrameInfoData.decode(readValue(buffer)!);

      case 130:
        return WKNavigationActionData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Handles callbacks from an WKUIDelegate instance.
///
/// See https://developer.apple.com/documentation/webkit/wkuidelegate?language=objc.
abstract class WKUIDelegateFlutterApi {
  static const MessageCodec<Object?> codec = _WKUIDelegateFlutterApiCodec();

  void onCreateWebView(int identifier, int webViewIdentifier,
      int configurationIdentifier, WKNavigationActionData navigationAction);

  static void setup(WKUIDelegateFlutterApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMessageHandler(null);
      } else {
        channel.setMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_identifier = (args[0] as int?);
          assert(arg_identifier != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView was null, expected non-null int.');
          final int? arg_configurationIdentifier = (args[2] as int?);
          assert(arg_configurationIdentifier != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView was null, expected non-null int.');
          final WKNavigationActionData? arg_navigationAction =
              (args[3] as WKNavigationActionData?);
          assert(arg_navigationAction != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView was null, expected non-null WKNavigationActionData.');
          api.onCreateWebView(arg_identifier!, arg_webViewIdentifier!,
              arg_configurationIdentifier!, arg_navigationAction!);
          return;
        });
      }
    }
  }
}

class _WKHttpCookieStoreHostApiCodec extends StandardMessageCodec {
  const _WKHttpCookieStoreHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSHttpCookieData) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is NSHttpCookiePropertyKeyEnumData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return NSHttpCookieData.decode(readValue(buffer)!);

      case 129:
        return NSHttpCookiePropertyKeyEnumData.decode(readValue(buffer)!);

      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

/// Mirror of WKHttpCookieStore.
///
/// See https://developer.apple.com/documentation/webkit/wkhttpcookiestore?language=objc.
class WKHttpCookieStoreHostApi {
  /// Constructor for [WKHttpCookieStoreHostApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  WKHttpCookieStoreHostApi({BinaryMessenger? binaryMessenger})
      : _binaryMessenger = binaryMessenger;
  final BinaryMessenger? _binaryMessenger;

  static const MessageCodec<Object?> codec = _WKHttpCookieStoreHostApiCodec();

  Future<void> createFromWebsiteDataStore(
      int arg_identifier, int arg_websiteDataStoreIdentifier) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore',
        codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
            .send(<Object?>[arg_identifier, arg_websiteDataStoreIdentifier])
        as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }

  Future<void> setCookie(
      int arg_identifier, NSHttpCookieData arg_cookie) async {
    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
        'dev.flutter.pigeon.WKHttpCookieStoreHostApi.setCookie', codec,
        binaryMessenger: _binaryMessenger);
    final List<Object?>? replyList = await channel
        .send(<Object?>[arg_identifier, arg_cookie]) as List<Object?>?;
    if (replyList == null) {
      throw PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel.',
      );
    } else if (replyList.length > 1) {
      throw PlatformException(
        code: replyList[0]! as String,
        message: replyList[1] as String?,
        details: replyList[2],
      );
    } else {
      return;
    }
  }
}
