// 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 (v2.0.3), 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
// ignore_for_file: avoid_relative_lib_imports
// @dart = 2.12
import 'dart:async';
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

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

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

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

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

abstract class TestWKWebsiteDataStoreHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKWebsiteDataStoreHostApiCodec();

  void createFromWebViewConfiguration(
      int instanceId, int configurationInstanceId);
  void createDefaultDataStore(int instanceId);
  Future<bool> removeDataOfTypes(
      int instanceId,
      List<WKWebsiteDataTypesEnumData?> dataTypes,
      double secondsModifiedSinceEpoch);
  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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationInstanceId = (args[1] as int?);
          assert(arg_configurationInstanceId != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_instanceId!, arg_configurationInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createDefaultDataStore was null, expected non-null int.');
          api.createDefaultDataStore(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null int.');
          final List<WKWebsiteDataTypesEnumData?>? arg_dataTypes =
              (args[1] as List<Object?>?)?.cast<WKWebsiteDataTypesEnumData?>();
          assert(arg_dataTypes != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null List<WKWebsiteDataTypesEnumData?>.');
          final double? arg_secondsModifiedSinceEpoch = (args[2] as double?);
          assert(arg_secondsModifiedSinceEpoch != null,
              'Argument for dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes was null, expected non-null double.');
          final bool output = await api.removeDataOfTypes(
              arg_instanceId!, arg_dataTypes!, arg_secondsModifiedSinceEpoch!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
  }
}

class _TestUIViewHostApiCodec extends StandardMessageCodec {
  const _TestUIViewHostApiCodec();
}

abstract class TestUIViewHostApi {
  static const MessageCodec<Object?> codec = _TestUIViewHostApiCodec();

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

class _TestUIScrollViewHostApiCodec extends StandardMessageCodec {
  const _TestUIScrollViewHostApiCodec();
}

abstract class TestUIScrollViewHostApi {
  static const MessageCodec<Object?> codec = _TestUIScrollViewHostApiCodec();

  void createFromWebView(int instanceId, int webViewInstanceId);
  List<double?> getContentOffset(int instanceId);
  void scrollBy(int instanceId, double x, double y);
  void setContentOffset(int instanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView was null, expected non-null int.');
          final int? arg_webViewInstanceId = (args[1] as int?);
          assert(arg_webViewInstanceId != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView was null, expected non-null int.');
          api.createFromWebView(arg_instanceId!, arg_webViewInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.UIScrollViewHostApi.getContentOffset was null, expected non-null int.');
          final List<double?> output = api.getContentOffset(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_x!, arg_y!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_x!, arg_y!);
          return <Object?, 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);
    }
  }
}

abstract class TestWKWebViewConfigurationHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKWebViewConfigurationHostApiCodec();

  void create(int instanceId);
  void createFromWebView(int instanceId, int webViewInstanceId);
  void setAllowsInlineMediaPlayback(int instanceId, bool allow);
  void setMediaTypesRequiringUserActionForPlayback(
      int instanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView was null, expected non-null int.');
          final int? arg_webViewInstanceId = (args[1] as int?);
          assert(arg_webViewInstanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView was null, expected non-null int.');
          api.createFromWebView(arg_instanceId!, arg_webViewInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_allow!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_types!);
          return <Object?, 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);
    }
  }
}

abstract class TestWKUserContentControllerHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKUserContentControllerHostApiCodec();

  void createFromWebViewConfiguration(
      int instanceId, int configurationInstanceId);
  void addScriptMessageHandler(
      int instanceId, int handlerInstanceid, String name);
  void removeScriptMessageHandler(int instanceId, String name);
  void removeAllScriptMessageHandlers(int instanceId);
  void addUserScript(int instanceId, WKUserScriptData userScript);
  void removeAllUserScripts(int instanceId);
  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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationInstanceId = (args[1] as int?);
          assert(arg_configurationInstanceId != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_instanceId!, arg_configurationInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler was null, expected non-null int.');
          final int? arg_handlerInstanceid = (args[1] as int?);
          assert(arg_handlerInstanceid != 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_instanceId!, arg_handlerInstanceid!, arg_name!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_name!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllScriptMessageHandlers was null, expected non-null int.');
          api.removeAllScriptMessageHandlers(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_userScript!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllUserScripts was null, expected non-null int.');
          api.removeAllUserScripts(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWKPreferencesHostApiCodec extends StandardMessageCodec {
  const _TestWKPreferencesHostApiCodec();
}

abstract class TestWKPreferencesHostApi {
  static const MessageCodec<Object?> codec = _TestWKPreferencesHostApiCodec();

  void createFromWebViewConfiguration(
      int instanceId, int configurationInstanceId);
  void setJavaScriptEnabled(int instanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          final int? arg_configurationInstanceId = (args[1] as int?);
          assert(arg_configurationInstanceId != null,
              'Argument for dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration was null, expected non-null int.');
          api.createFromWebViewConfiguration(
              arg_instanceId!, arg_configurationInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_enabled!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWKScriptMessageHandlerHostApiCodec extends StandardMessageCodec {
  const _TestWKScriptMessageHandlerHostApiCodec();
}

abstract class TestWKScriptMessageHandlerHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKScriptMessageHandlerHostApiCodec();

  void create(int instanceId);
  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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKScriptMessageHandlerHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWKNavigationDelegateHostApiCodec extends StandardMessageCodec {
  const _TestWKNavigationDelegateHostApiCodec();
}

abstract class TestWKNavigationDelegateHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKNavigationDelegateHostApiCodec();

  void create(int instanceId);
  void setDidFinishNavigation(int instanceId, int? functionInstanceId);
  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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null, expected non-null int.');
          final int? arg_functionInstanceId = (args[1] as int?);
          assert(arg_functionInstanceId != null,
              'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null, expected non-null int.');
          api.setDidFinishNavigation(arg_instanceId!, arg_functionInstanceId!);
          return <Object?, 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);
    }
  }
}

abstract class TestNSObjectHostApi {
  static const MessageCodec<Object?> codec = _TestNSObjectHostApiCodec();

  void dispose(int instanceId);
  void addObserver(int instanceId, int observerInstanceId, String keyPath,
      List<NSKeyValueObservingOptionsEnumData?> options);
  void removeObserver(int instanceId, int observerInstanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.dispose was null, expected non-null int.');
          api.dispose(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.addObserver was null, expected non-null int.');
          final int? arg_observerInstanceId = (args[1] as int?);
          assert(arg_observerInstanceId != 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_instanceId!, arg_observerInstanceId!,
              arg_keyPath!, arg_options!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.NSObjectHostApi.removeObserver was null, expected non-null int.');
          final int? arg_observerInstanceId = (args[1] as int?);
          assert(arg_observerInstanceId != 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_instanceId!, arg_observerInstanceId!, arg_keyPath!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWKWebViewHostApiCodec extends StandardMessageCodec {
  const _TestWKWebViewHostApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is NSUrlRequestData) {
      buffer.putUint8(128);
      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)!);

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

abstract class TestWKWebViewHostApi {
  static const MessageCodec<Object?> codec = _TestWKWebViewHostApiCodec();

  void create(int instanceId, int configurationInstanceId);
  void setUIDelegate(int instanceId, int? uiDelegateInstanceId);
  void setNavigationDelegate(int instanceId, int? navigationDelegateInstanceId);
  String? getUrl(int instanceId);
  double getEstimatedProgress(int instanceId);
  void loadRequest(int instanceId, NSUrlRequestData request);
  void loadHtmlString(int instanceId, String string, String? baseUrl);
  void loadFileUrl(int instanceId, String url, String readAccessUrl);
  void loadFlutterAsset(int instanceId, String key);
  bool canGoBack(int instanceId);
  bool canGoForward(int instanceId);
  void goBack(int instanceId);
  void goForward(int instanceId);
  void reload(int instanceId);
  String? getTitle(int instanceId);
  void setAllowsBackForwardNavigationGestures(int instanceId, bool allow);
  void setCustomUserAgent(int instanceId, String? userAgent);
  Future<String> evaluateJavaScript(int instanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.create was null, expected non-null int.');
          final int? arg_configurationInstanceId = (args[1] as int?);
          assert(arg_configurationInstanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!, arg_configurationInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate was null, expected non-null int.');
          final int? arg_uiDelegateInstanceId = (args[1] as int?);
          assert(arg_uiDelegateInstanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate was null, expected non-null int.');
          api.setUIDelegate(arg_instanceId!, arg_uiDelegateInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate was null, expected non-null int.');
          final int? arg_navigationDelegateInstanceId = (args[1] as int?);
          assert(arg_navigationDelegateInstanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate was null, expected non-null int.');
          api.setNavigationDelegate(
              arg_instanceId!, arg_navigationDelegateInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getUrl was null, expected non-null int.');
          final String? output = api.getUrl(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getEstimatedProgress was null, expected non-null int.');
          final double output = api.getEstimatedProgress(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_request!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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?);
          assert(arg_baseUrl != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString was null, expected non-null String.');
          api.loadHtmlString(arg_instanceId!, arg_string!, arg_baseUrl!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_url!, arg_readAccessUrl!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_key!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.canGoBack was null, expected non-null int.');
          final bool output = api.canGoBack(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.canGoForward was null, expected non-null int.');
          final bool output = api.canGoForward(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.goBack was null, expected non-null int.');
          api.goBack(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.goForward was null, expected non-null int.');
          api.goForward(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.reload was null, expected non-null int.');
          api.reload(arg_instanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.getTitle was null, expected non-null int.');
          final String? output = api.getTitle(arg_instanceId!);
          return <Object?, Object?>{'result': 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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_instanceId!, arg_allow!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent was null, expected non-null int.');
          final String? arg_userAgent = (args[1] as String?);
          assert(arg_userAgent != null,
              'Argument for dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent was null, expected non-null String.');
          api.setCustomUserAgent(arg_instanceId!, arg_userAgent!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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 String output = await api.evaluateJavaScript(
              arg_instanceId!, arg_javascriptString!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
  }
}

class _TestWKUIDelegateHostApiCodec extends StandardMessageCodec {
  const _TestWKUIDelegateHostApiCodec();
}

abstract class TestWKUIDelegateHostApi {
  static const MessageCodec<Object?> codec = _TestWKUIDelegateHostApiCodec();

  void create(int instanceId);
  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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKUIDelegateHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!);
          return <Object?, 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);
    }
  }
}

abstract class TestWKHttpCookieStoreHostApi {
  static const MessageCodec<Object?> codec =
      _TestWKHttpCookieStoreHostApiCodec();

  void createFromWebsiteDataStore(
      int instanceId, int websiteDataStoreInstanceId);
  void setCookie(int instanceId, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore was null, expected non-null int.');
          final int? arg_websiteDataStoreInstanceId = (args[1] as int?);
          assert(arg_websiteDataStoreInstanceId != null,
              'Argument for dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore was null, expected non-null int.');
          api.createFromWebsiteDataStore(
              arg_instanceId!, arg_websiteDataStoreInstanceId!);
          return <Object?, 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_instanceId = (args[0] as int?);
          assert(arg_instanceId != 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.');
          api.setCookie(arg_instanceId!, arg_cookie!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}
