// 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, unnecessary_import
// ignore_for_file: avoid_relative_lib_imports
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';
import 'package:flutter_test/flutter_test.dart';

import 'package:webview_flutter_wkwebview/src/common/web_kit.g.dart';

class _TestWKWebsiteDataStoreHostApiCodec extends StandardMessageCodec {
  const _TestWKWebsiteDataStoreHostApiCodec();
  @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.
abstract class TestWKWebsiteDataStoreHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKWebsiteDataStoreHostApiCodec();

  void createFromWebViewConfiguration(
      int identifier, int configurationIdentifier);

  void createDefaultDataStore(int identifier);

  Future<bool> removeDataOfTypes(
      int identifier,
      List<WKWebsiteDataTypeEnumData?> dataTypes,
      double modificationTimeInSecondsSinceEpoch);

  static void setup(TestWKWebsiteDataStoreHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration 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.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationIdentifier = (args[1] as int?);
          assert(arg_configurationIdentifier != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_identifier!, arg_configurationIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createDefaultDataStore',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createDefaultDataStore 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.WKWebsiteDataStoreHostApi.createDefaultDataStore was null, expected non-null int.');
          api.createDefaultDataStore(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes 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.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null int.');
          final List<WKWebsiteDataTypeEnumData?>? arg_dataTypes =
              (args[1] as List<Object?>?)?.cast<WKWebsiteDataTypeEnumData?>();
          assert(arg_dataTypes != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null List<WKWebsiteDataTypeEnumData?>.');
          final double? arg_modificationTimeInSecondsSinceEpoch =
              (args[2] as double?);
          assert(arg_modificationTimeInSecondsSinceEpoch != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null double.');
          final bool output = await api.removeDataOfTypes(arg_identifier!,
              arg_dataTypes!, arg_modificationTimeInSecondsSinceEpoch!);
          return <Object?>[output];
        });
      }
    }
  }
}

/// Mirror of UIView.
///
/// See https://developer.apple.com/documentation/uikit/uiview?language=objc.
abstract class TestUIViewHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void setBackgroundColor(int identifier, int? value);

  void setOpaque(int identifier, bool opaque);

  static void setup(TestUIViewHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIViewHostApi.setBackgroundColor', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIViewHostApi.setBackgroundColor 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.UIViewHostApi.setBackgroundColor was null, expected non-null int.');
          final int? arg_value = (args[1] as int?);
          api.setBackgroundColor(arg_identifier!, arg_value);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIViewHostApi.setOpaque', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIViewHostApi.setOpaque 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.UIViewHostApi.setOpaque was null, expected non-null int.');
          final bool? arg_opaque = (args[1] as bool?);
          assert(arg_opaque != null,
              'Argument for dev.flutter.pigeon.UIViewHostApi.setOpaque was null, expected non-null bool.');
          api.setOpaque(arg_identifier!, arg_opaque!);
          return <Object?>[];
        });
      }
    }
  }
}

/// Mirror of UIScrollView.
///
/// See https://developer.apple.com/documentation/uikit/uiscrollview?language=objc.
abstract class TestUIScrollViewHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void createFromWebView(int identifier, int webViewIdentifier);

  List<double?> getContentOffset(int identifier);

  void scrollBy(int identifier, double x, double y);

  void setContentOffset(int identifier, double x, double y);

  static void setup(TestUIScrollViewHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView 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.UIScrollViewHostApi.createFromWebView was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView was null, expected non-null int.');
          api.createFromWebView(arg_identifier!, arg_webViewIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIScrollViewHostApi.getContentOffset', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.getContentOffset 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.UIScrollViewHostApi.getContentOffset was null, expected non-null int.');
          final List<double?> output = api.getContentOffset(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIScrollViewHostApi.scrollBy', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.scrollBy 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.UIScrollViewHostApi.scrollBy was null, expected non-null int.');
          final double? arg_x = (args[1] as double?);
          assert(arg_x != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.scrollBy was null, expected non-null double.');
          final double? arg_y = (args[2] as double?);
          assert(arg_y != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.scrollBy was null, expected non-null double.');
          api.scrollBy(arg_identifier!, arg_x!, arg_y!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset 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.UIScrollViewHostApi.setContentOffset was null, expected non-null int.');
          final double? arg_x = (args[1] as double?);
          assert(arg_x != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset was null, expected non-null double.');
          final double? arg_y = (args[2] as double?);
          assert(arg_y != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset was null, expected non-null double.');
          api.setContentOffset(arg_identifier!, arg_x!, arg_y!);
          return <Object?>[];
        });
      }
    }
  }
}

class _TestWKWebViewConfigurationHostApiCodec extends StandardMessageCodec {
  const _TestWKWebViewConfigurationHostApiCodec();
  @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.
abstract class TestWKWebViewConfigurationHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKWebViewConfigurationHostApiCodec();

  void create(int identifier);

  void createFromWebView(int identifier, int webViewIdentifier);

  void setAllowsInlineMediaPlayback(int identifier, bool allow);

  void setMediaTypesRequiringUserActionForPlayback(
      int identifier, List<WKAudiovisualMediaTypeEnumData?> types);

  static void setup(TestWKWebViewConfigurationHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewConfigurationHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.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.WKWebViewConfigurationHostApi.create was null, expected non-null int.');
          api.create(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView 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.WKWebViewConfigurationHostApi.createFromWebView was null, expected non-null int.');
          final int? arg_webViewIdentifier = (args[1] as int?);
          assert(arg_webViewIdentifier != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView was null, expected non-null int.');
          api.createFromWebView(arg_identifier!, arg_webViewIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback 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.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback was null, expected non-null int.');
          final bool? arg_allow = (args[1] as bool?);
          assert(arg_allow != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback was null, expected non-null bool.');
          api.setAllowsInlineMediaPlayback(arg_identifier!, arg_allow!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback 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.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback was null, expected non-null int.');
          final List<WKAudiovisualMediaTypeEnumData?>? arg_types =
              (args[1] as List<Object?>?)
                  ?.cast<WKAudiovisualMediaTypeEnumData?>();
          assert(arg_types != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.setMediaTypesRequiringUserActionForPlayback was null, expected non-null List<WKAudiovisualMediaTypeEnumData?>.');
          api.setMediaTypesRequiringUserActionForPlayback(
              arg_identifier!, arg_types!);
          return <Object?>[];
        });
      }
    }
  }
}

class _TestWKUserContentControllerHostApiCodec extends StandardMessageCodec {
  const _TestWKUserContentControllerHostApiCodec();
  @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.
abstract class TestWKUserContentControllerHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKUserContentControllerHostApiCodec();

  void createFromWebViewConfiguration(
      int identifier, int configurationIdentifier);

  void addScriptMessageHandler(
      int identifier, int handlerIdentifier, String name);

  void removeScriptMessageHandler(int identifier, String name);

  void removeAllScriptMessageHandlers(int identifier);

  void addUserScript(int identifier, WKUserScriptData userScript);

  void removeAllUserScripts(int identifier);

  static void setup(TestWKUserContentControllerHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration 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.WKUserContentControllerHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationIdentifier = (args[1] as int?);
          assert(arg_configurationIdentifier != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_identifier!, arg_configurationIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler 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.WKUserContentControllerHostApi.addScriptMessageHandler was null, expected non-null int.');
          final int? arg_handlerIdentifier = (args[1] as int?);
          assert(arg_handlerIdentifier != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler was null, expected non-null int.');
          final String? arg_name = (args[2] as String?);
          assert(arg_name != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler was null, expected non-null String.');
          api.addScriptMessageHandler(
              arg_identifier!, arg_handlerIdentifier!, arg_name!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.removeScriptMessageHandler',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeScriptMessageHandler 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.WKUserContentControllerHostApi.removeScriptMessageHandler was null, expected non-null int.');
          final String? arg_name = (args[1] as String?);
          assert(arg_name != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeScriptMessageHandler was null, expected non-null String.');
          api.removeScriptMessageHandler(arg_identifier!, arg_name!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllScriptMessageHandlers',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllScriptMessageHandlers 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.WKUserContentControllerHostApi.removeAllScriptMessageHandlers was null, expected non-null int.');
          api.removeAllScriptMessageHandlers(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.addUserScript',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addUserScript 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.WKUserContentControllerHostApi.addUserScript was null, expected non-null int.');
          final WKUserScriptData? arg_userScript =
              (args[1] as WKUserScriptData?);
          assert(arg_userScript != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addUserScript was null, expected non-null WKUserScriptData.');
          api.addUserScript(arg_identifier!, arg_userScript!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllUserScripts',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllUserScripts 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.WKUserContentControllerHostApi.removeAllUserScripts was null, expected non-null int.');
          api.removeAllUserScripts(arg_identifier!);
          return <Object?>[];
        });
      }
    }
  }
}

/// Mirror of WKUserPreferences.
///
/// See https://developer.apple.com/documentation/webkit/wkpreferences?language=objc.
abstract class TestWKPreferencesHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void createFromWebViewConfiguration(
      int identifier, int configurationIdentifier);

  void setJavaScriptEnabled(int identifier, bool enabled);

  static void setup(TestWKPreferencesHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration 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.WKPreferencesHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationIdentifier = (args[1] as int?);
          assert(arg_configurationIdentifier != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_identifier!, arg_configurationIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKPreferencesHostApi.setJavaScriptEnabled', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.setJavaScriptEnabled 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.WKPreferencesHostApi.setJavaScriptEnabled was null, expected non-null int.');
          final bool? arg_enabled = (args[1] as bool?);
          assert(arg_enabled != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.setJavaScriptEnabled was null, expected non-null bool.');
          api.setJavaScriptEnabled(arg_identifier!, arg_enabled!);
          return <Object?>[];
        });
      }
    }
  }
}

/// Mirror of WKScriptMessageHandler.
///
/// See https://developer.apple.com/documentation/webkit/wkscriptmessagehandler?language=objc.
abstract class TestWKScriptMessageHandlerHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void create(int identifier);

  static void setup(TestWKScriptMessageHandlerHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKScriptMessageHandlerHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerHostApi.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.WKScriptMessageHandlerHostApi.create was null, expected non-null int.');
          api.create(arg_identifier!);
          return <Object?>[];
        });
      }
    }
  }
}

/// Mirror of WKNavigationDelegate.
///
/// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc.
abstract class TestWKNavigationDelegateHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void create(int identifier);

  static void setup(TestWKNavigationDelegateHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.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.WKNavigationDelegateHostApi.create was null, expected non-null int.');
          api.create(arg_identifier!);
          return <Object?>[];
        });
      }
    }
  }
}

class _TestNSObjectHostApiCodec extends StandardMessageCodec {
  const _TestNSObjectHostApiCodec();
  @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.
abstract class TestNSObjectHostApi {
  static const MessageCodec<Object?> codec = _TestNSObjectHostApiCodec();

  void dispose(int identifier);

  void addObserver(int identifier, int observerIdentifier, String keyPath,
      List<NSKeyValueObservingOptionsEnumData?> options);

  void removeObserver(int identifier, int observerIdentifier, String keyPath);

  static void setup(TestNSObjectHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.NSObjectHostApi.dispose', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.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.NSObjectHostApi.dispose was null, expected non-null int.');
          api.dispose(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.NSObjectHostApi.addObserver', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.addObserver 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.NSObjectHostApi.addObserver was null, expected non-null int.');
          final int? arg_observerIdentifier = (args[1] as int?);
          assert(arg_observerIdentifier != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.addObserver was null, expected non-null int.');
          final String? arg_keyPath = (args[2] as String?);
          assert(arg_keyPath != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.addObserver was null, expected non-null String.');
          final List<NSKeyValueObservingOptionsEnumData?>? arg_options =
              (args[3] as List<Object?>?)
                  ?.cast<NSKeyValueObservingOptionsEnumData?>();
          assert(arg_options != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.addObserver was null, expected non-null List<NSKeyValueObservingOptionsEnumData?>.');
          api.addObserver(arg_identifier!, arg_observerIdentifier!,
              arg_keyPath!, arg_options!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.NSObjectHostApi.removeObserver', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.removeObserver 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.NSObjectHostApi.removeObserver was null, expected non-null int.');
          final int? arg_observerIdentifier = (args[1] as int?);
          assert(arg_observerIdentifier != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.removeObserver was null, expected non-null int.');
          final String? arg_keyPath = (args[2] as String?);
          assert(arg_keyPath != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.removeObserver was null, expected non-null String.');
          api.removeObserver(
              arg_identifier!, arg_observerIdentifier!, arg_keyPath!);
          return <Object?>[];
        });
      }
    }
  }
}

class _TestWKWebViewHostApiCodec extends StandardMessageCodec {
  const _TestWKWebViewHostApiCodec();
  @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.
abstract class TestWKWebViewHostApi {
  static const MessageCodec<Object?> codec = _TestWKWebViewHostApiCodec();

  void create(int identifier, int configurationIdentifier);

  void setUIDelegate(int identifier, int? uiDelegateIdentifier);

  void setNavigationDelegate(int identifier, int? navigationDelegateIdentifier);

  String? getUrl(int identifier);

  double getEstimatedProgress(int identifier);

  void loadRequest(int identifier, NSUrlRequestData request);

  void loadHtmlString(int identifier, String string, String? baseUrl);

  void loadFileUrl(int identifier, String url, String readAccessUrl);

  void loadFlutterAsset(int identifier, String key);

  bool canGoBack(int identifier);

  bool canGoForward(int identifier);

  void goBack(int identifier);

  void goForward(int identifier);

  void reload(int identifier);

  String? getTitle(int identifier);

  void setAllowsBackForwardNavigationGestures(int identifier, bool allow);

  void setCustomUserAgent(int identifier, String? userAgent);

  Future<Object?> evaluateJavaScript(int identifier, String javaScriptString);

  static void setup(TestWKWebViewHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.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.WKWebViewHostApi.create was null, expected non-null int.');
          final int? arg_configurationIdentifier = (args[1] as int?);
          assert(arg_configurationIdentifier != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.create was null, expected non-null int.');
          api.create(arg_identifier!, arg_configurationIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate 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.WKWebViewHostApi.setUIDelegate was null, expected non-null int.');
          final int? arg_uiDelegateIdentifier = (args[1] as int?);
          api.setUIDelegate(arg_identifier!, arg_uiDelegateIdentifier);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate 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.WKWebViewHostApi.setNavigationDelegate was null, expected non-null int.');
          final int? arg_navigationDelegateIdentifier = (args[1] as int?);
          api.setNavigationDelegate(
              arg_identifier!, arg_navigationDelegateIdentifier);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.getUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getUrl 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.WKWebViewHostApi.getUrl was null, expected non-null int.');
          final String? output = api.getUrl(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.getEstimatedProgress', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getEstimatedProgress 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.WKWebViewHostApi.getEstimatedProgress was null, expected non-null int.');
          final double output = api.getEstimatedProgress(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.loadRequest', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadRequest 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.WKWebViewHostApi.loadRequest was null, expected non-null int.');
          final NSUrlRequestData? arg_request = (args[1] as NSUrlRequestData?);
          assert(arg_request != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadRequest was null, expected non-null NSUrlRequestData.');
          api.loadRequest(arg_identifier!, arg_request!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString 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.WKWebViewHostApi.loadHtmlString was null, expected non-null int.');
          final String? arg_string = (args[1] as String?);
          assert(arg_string != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString was null, expected non-null String.');
          final String? arg_baseUrl = (args[2] as String?);
          api.loadHtmlString(arg_identifier!, arg_string!, arg_baseUrl);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl 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.WKWebViewHostApi.loadFileUrl was null, expected non-null int.');
          final String? arg_url = (args[1] as String?);
          assert(arg_url != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl was null, expected non-null String.');
          final String? arg_readAccessUrl = (args[2] as String?);
          assert(arg_readAccessUrl != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl was null, expected non-null String.');
          api.loadFileUrl(arg_identifier!, arg_url!, arg_readAccessUrl!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.loadFlutterAsset', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadFlutterAsset 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.WKWebViewHostApi.loadFlutterAsset was null, expected non-null int.');
          final String? arg_key = (args[1] as String?);
          assert(arg_key != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadFlutterAsset was null, expected non-null String.');
          api.loadFlutterAsset(arg_identifier!, arg_key!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.canGoBack', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.canGoBack 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.WKWebViewHostApi.canGoBack was null, expected non-null int.');
          final bool output = api.canGoBack(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.canGoForward', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.canGoForward 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.WKWebViewHostApi.canGoForward was null, expected non-null int.');
          final bool output = api.canGoForward(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.goBack', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.goBack 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.WKWebViewHostApi.goBack was null, expected non-null int.');
          api.goBack(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.goForward', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.goForward 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.WKWebViewHostApi.goForward was null, expected non-null int.');
          api.goForward(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.reload', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.reload 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.WKWebViewHostApi.reload was null, expected non-null int.');
          api.reload(arg_identifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.getTitle', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getTitle 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.WKWebViewHostApi.getTitle was null, expected non-null int.');
          final String? output = api.getTitle(arg_identifier!);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.setAllowsBackForwardNavigationGestures',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setAllowsBackForwardNavigationGestures 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.WKWebViewHostApi.setAllowsBackForwardNavigationGestures was null, expected non-null int.');
          final bool? arg_allow = (args[1] as bool?);
          assert(arg_allow != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setAllowsBackForwardNavigationGestures was null, expected non-null bool.');
          api.setAllowsBackForwardNavigationGestures(
              arg_identifier!, arg_allow!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent 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.WKWebViewHostApi.setCustomUserAgent was null, expected non-null int.');
          final String? arg_userAgent = (args[1] as String?);
          api.setCustomUserAgent(arg_identifier!, arg_userAgent);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKWebViewHostApi.evaluateJavaScript', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.evaluateJavaScript 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.WKWebViewHostApi.evaluateJavaScript was null, expected non-null int.');
          final String? arg_javaScriptString = (args[1] as String?);
          assert(arg_javaScriptString != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.evaluateJavaScript was null, expected non-null String.');
          final Object? output = await api.evaluateJavaScript(
              arg_identifier!, arg_javaScriptString!);
          return <Object?>[output];
        });
      }
    }
  }
}

/// Mirror of WKUIDelegate.
///
/// See https://developer.apple.com/documentation/webkit/wkuidelegate?language=objc.
abstract class TestWKUIDelegateHostApi {
  static const MessageCodec<Object?> codec = StandardMessageCodec();

  void create(int identifier);

  static void setup(TestWKUIDelegateHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKUIDelegateHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateHostApi.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.WKUIDelegateHostApi.create was null, expected non-null int.');
          api.create(arg_identifier!);
          return <Object?>[];
        });
      }
    }
  }
}

class _TestWKHttpCookieStoreHostApiCodec extends StandardMessageCodec {
  const _TestWKHttpCookieStoreHostApiCodec();
  @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.
abstract class TestWKHttpCookieStoreHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKHttpCookieStoreHostApiCodec();

  void createFromWebsiteDataStore(
      int identifier, int websiteDataStoreIdentifier);

  Future<void> setCookie(int identifier, NSHttpCookieData cookie);

  static void setup(TestWKHttpCookieStoreHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore 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.WKHttpCookieStoreHostApi.createFromWebsiteDataStore was null, expected non-null int.');
          final int? arg_websiteDataStoreIdentifier = (args[1] as int?);
          assert(arg_websiteDataStoreIdentifier != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore was null, expected non-null int.');
          api.createFromWebsiteDataStore(
              arg_identifier!, arg_websiteDataStoreIdentifier!);
          return <Object?>[];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKHttpCookieStoreHostApi.setCookie', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.setCookie 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.WKHttpCookieStoreHostApi.setCookie was null, expected non-null int.');
          final NSHttpCookieData? arg_cookie = (args[1] as NSHttpCookieData?);
          assert(arg_cookie != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.setCookie was null, expected non-null NSHttpCookieData.');
          await api.setCookie(arg_identifier!, arg_cookie!);
          return <Object?>[];
        });
      }
    }
  }
}
