// 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.12), do not edit directly.
// See also: https://pub.dev/packages/pigeon

#undef _HAS_EXCEPTIONS

#include "core_tests.gen.h"

#include <flutter/basic_message_channel.h>
#include <flutter/binary_messenger.h>
#include <flutter/encodable_value.h>
#include <flutter/standard_message_codec.h>

#include <map>
#include <optional>
#include <string>

namespace core_tests_pigeontest {

// AllTypes

bool AllTypes::a_bool() const { return a_bool_; }
void AllTypes::set_a_bool(bool value_arg) { a_bool_ = value_arg; }

int64_t AllTypes::an_int() const { return an_int_; }
void AllTypes::set_an_int(int64_t value_arg) { an_int_ = value_arg; }

double AllTypes::a_double() const { return a_double_; }
void AllTypes::set_a_double(double value_arg) { a_double_ = value_arg; }

const std::string& AllTypes::a_string() const { return a_string_; }
void AllTypes::set_a_string(std::string_view value_arg) {
  a_string_ = value_arg;
}

const std::vector<uint8_t>& AllTypes::a_byte_array() const {
  return a_byte_array_;
}
void AllTypes::set_a_byte_array(const std::vector<uint8_t>& value_arg) {
  a_byte_array_ = value_arg;
}

const std::vector<int32_t>& AllTypes::a4_byte_array() const {
  return a4_byte_array_;
}
void AllTypes::set_a4_byte_array(const std::vector<int32_t>& value_arg) {
  a4_byte_array_ = value_arg;
}

const std::vector<int64_t>& AllTypes::a8_byte_array() const {
  return a8_byte_array_;
}
void AllTypes::set_a8_byte_array(const std::vector<int64_t>& value_arg) {
  a8_byte_array_ = value_arg;
}

const std::vector<double>& AllTypes::a_float_array() const {
  return a_float_array_;
}
void AllTypes::set_a_float_array(const std::vector<double>& value_arg) {
  a_float_array_ = value_arg;
}

const flutter::EncodableList& AllTypes::a_list() const { return a_list_; }
void AllTypes::set_a_list(const flutter::EncodableList& value_arg) {
  a_list_ = value_arg;
}

const flutter::EncodableMap& AllTypes::a_map() const { return a_map_; }
void AllTypes::set_a_map(const flutter::EncodableMap& value_arg) {
  a_map_ = value_arg;
}

const AnEnum& AllTypes::an_enum() const { return an_enum_; }
void AllTypes::set_an_enum(const AnEnum& value_arg) { an_enum_ = value_arg; }

flutter::EncodableList AllTypes::ToEncodableList() const {
  return flutter::EncodableList{
      flutter::EncodableValue(a_bool_),
      flutter::EncodableValue(an_int_),
      flutter::EncodableValue(a_double_),
      flutter::EncodableValue(a_string_),
      flutter::EncodableValue(a_byte_array_),
      flutter::EncodableValue(a4_byte_array_),
      flutter::EncodableValue(a8_byte_array_),
      flutter::EncodableValue(a_float_array_),
      flutter::EncodableValue(a_list_),
      flutter::EncodableValue(a_map_),
      flutter::EncodableValue((int)an_enum_),
  };
}

AllTypes::AllTypes() {}

AllTypes::AllTypes(const flutter::EncodableList& list) {
  auto& encodable_a_bool = list[0];
  if (const bool* pointer_a_bool = std::get_if<bool>(&encodable_a_bool)) {
    a_bool_ = *pointer_a_bool;
  }
  auto& encodable_an_int = list[1];
  if (const int32_t* pointer_an_int = std::get_if<int32_t>(&encodable_an_int))
    an_int_ = *pointer_an_int;
  else if (const int64_t* pointer_an_int_64 =
               std::get_if<int64_t>(&encodable_an_int))
    an_int_ = *pointer_an_int_64;
  auto& encodable_a_double = list[2];
  if (const double* pointer_a_double =
          std::get_if<double>(&encodable_a_double)) {
    a_double_ = *pointer_a_double;
  }
  auto& encodable_a_string = list[3];
  if (const std::string* pointer_a_string =
          std::get_if<std::string>(&encodable_a_string)) {
    a_string_ = *pointer_a_string;
  }
  auto& encodable_a_byte_array = list[4];
  if (const std::vector<uint8_t>* pointer_a_byte_array =
          std::get_if<std::vector<uint8_t>>(&encodable_a_byte_array)) {
    a_byte_array_ = *pointer_a_byte_array;
  }
  auto& encodable_a4_byte_array = list[5];
  if (const std::vector<int32_t>* pointer_a4_byte_array =
          std::get_if<std::vector<int32_t>>(&encodable_a4_byte_array)) {
    a4_byte_array_ = *pointer_a4_byte_array;
  }
  auto& encodable_a8_byte_array = list[6];
  if (const std::vector<int64_t>* pointer_a8_byte_array =
          std::get_if<std::vector<int64_t>>(&encodable_a8_byte_array)) {
    a8_byte_array_ = *pointer_a8_byte_array;
  }
  auto& encodable_a_float_array = list[7];
  if (const std::vector<double>* pointer_a_float_array =
          std::get_if<std::vector<double>>(&encodable_a_float_array)) {
    a_float_array_ = *pointer_a_float_array;
  }
  auto& encodable_a_list = list[8];
  if (const flutter::EncodableList* pointer_a_list =
          std::get_if<flutter::EncodableList>(&encodable_a_list)) {
    a_list_ = *pointer_a_list;
  }
  auto& encodable_a_map = list[9];
  if (const flutter::EncodableMap* pointer_a_map =
          std::get_if<flutter::EncodableMap>(&encodable_a_map)) {
    a_map_ = *pointer_a_map;
  }
  auto& encodable_an_enum = list[10];
  if (const int32_t* pointer_an_enum = std::get_if<int32_t>(&encodable_an_enum))
    an_enum_ = (AnEnum)*pointer_an_enum;
}

// AllNullableTypes

const bool* AllNullableTypes::a_nullable_bool() const {
  return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr;
}
void AllNullableTypes::set_a_nullable_bool(const bool* value_arg) {
  a_nullable_bool_ = value_arg ? std::optional<bool>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_bool(bool value_arg) {
  a_nullable_bool_ = value_arg;
}

const int64_t* AllNullableTypes::a_nullable_int() const {
  return a_nullable_int_ ? &(*a_nullable_int_) : nullptr;
}
void AllNullableTypes::set_a_nullable_int(const int64_t* value_arg) {
  a_nullable_int_ =
      value_arg ? std::optional<int64_t>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_int(int64_t value_arg) {
  a_nullable_int_ = value_arg;
}

const double* AllNullableTypes::a_nullable_double() const {
  return a_nullable_double_ ? &(*a_nullable_double_) : nullptr;
}
void AllNullableTypes::set_a_nullable_double(const double* value_arg) {
  a_nullable_double_ =
      value_arg ? std::optional<double>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_double(double value_arg) {
  a_nullable_double_ = value_arg;
}

const std::string* AllNullableTypes::a_nullable_string() const {
  return a_nullable_string_ ? &(*a_nullable_string_) : nullptr;
}
void AllNullableTypes::set_a_nullable_string(
    const std::string_view* value_arg) {
  a_nullable_string_ =
      value_arg ? std::optional<std::string>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_string(std::string_view value_arg) {
  a_nullable_string_ = value_arg;
}

const std::vector<uint8_t>* AllNullableTypes::a_nullable_byte_array() const {
  return a_nullable_byte_array_ ? &(*a_nullable_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable_byte_array(
    const std::vector<uint8_t>* value_arg) {
  a_nullable_byte_array_ = value_arg
                               ? std::optional<std::vector<uint8_t>>(*value_arg)
                               : std::nullopt;
}
void AllNullableTypes::set_a_nullable_byte_array(
    const std::vector<uint8_t>& value_arg) {
  a_nullable_byte_array_ = value_arg;
}

const std::vector<int32_t>* AllNullableTypes::a_nullable4_byte_array() const {
  return a_nullable4_byte_array_ ? &(*a_nullable4_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable4_byte_array(
    const std::vector<int32_t>* value_arg) {
  a_nullable4_byte_array_ =
      value_arg ? std::optional<std::vector<int32_t>>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_a_nullable4_byte_array(
    const std::vector<int32_t>& value_arg) {
  a_nullable4_byte_array_ = value_arg;
}

const std::vector<int64_t>* AllNullableTypes::a_nullable8_byte_array() const {
  return a_nullable8_byte_array_ ? &(*a_nullable8_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable8_byte_array(
    const std::vector<int64_t>* value_arg) {
  a_nullable8_byte_array_ =
      value_arg ? std::optional<std::vector<int64_t>>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_a_nullable8_byte_array(
    const std::vector<int64_t>& value_arg) {
  a_nullable8_byte_array_ = value_arg;
}

const std::vector<double>* AllNullableTypes::a_nullable_float_array() const {
  return a_nullable_float_array_ ? &(*a_nullable_float_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable_float_array(
    const std::vector<double>* value_arg) {
  a_nullable_float_array_ =
      value_arg ? std::optional<std::vector<double>>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_float_array(
    const std::vector<double>& value_arg) {
  a_nullable_float_array_ = value_arg;
}

const flutter::EncodableList* AllNullableTypes::a_nullable_list() const {
  return a_nullable_list_ ? &(*a_nullable_list_) : nullptr;
}
void AllNullableTypes::set_a_nullable_list(
    const flutter::EncodableList* value_arg) {
  a_nullable_list_ = value_arg
                         ? std::optional<flutter::EncodableList>(*value_arg)
                         : std::nullopt;
}
void AllNullableTypes::set_a_nullable_list(
    const flutter::EncodableList& value_arg) {
  a_nullable_list_ = value_arg;
}

const flutter::EncodableMap* AllNullableTypes::a_nullable_map() const {
  return a_nullable_map_ ? &(*a_nullable_map_) : nullptr;
}
void AllNullableTypes::set_a_nullable_map(
    const flutter::EncodableMap* value_arg) {
  a_nullable_map_ = value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
                              : std::nullopt;
}
void AllNullableTypes::set_a_nullable_map(
    const flutter::EncodableMap& value_arg) {
  a_nullable_map_ = value_arg;
}

const flutter::EncodableList* AllNullableTypes::nullable_nested_list() const {
  return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr;
}
void AllNullableTypes::set_nullable_nested_list(
    const flutter::EncodableList* value_arg) {
  nullable_nested_list_ =
      value_arg ? std::optional<flutter::EncodableList>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_nullable_nested_list(
    const flutter::EncodableList& value_arg) {
  nullable_nested_list_ = value_arg;
}

const flutter::EncodableMap* AllNullableTypes::nullable_map_with_annotations()
    const {
  return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_)
                                        : nullptr;
}
void AllNullableTypes::set_nullable_map_with_annotations(
    const flutter::EncodableMap* value_arg) {
  nullable_map_with_annotations_ =
      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_annotations(
    const flutter::EncodableMap& value_arg) {
  nullable_map_with_annotations_ = value_arg;
}

const flutter::EncodableMap* AllNullableTypes::nullable_map_with_object()
    const {
  return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr;
}
void AllNullableTypes::set_nullable_map_with_object(
    const flutter::EncodableMap* value_arg) {
  nullable_map_with_object_ =
      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_object(
    const flutter::EncodableMap& value_arg) {
  nullable_map_with_object_ = value_arg;
}

const AnEnum* AllNullableTypes::a_nullable_enum() const {
  return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr;
}
void AllNullableTypes::set_a_nullable_enum(const AnEnum* value_arg) {
  a_nullable_enum_ =
      value_arg ? std::optional<AnEnum>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_enum(const AnEnum& value_arg) {
  a_nullable_enum_ = value_arg;
}

flutter::EncodableList AllNullableTypes::ToEncodableList() const {
  return flutter::EncodableList{
      a_nullable_bool_ ? flutter::EncodableValue(*a_nullable_bool_)
                       : flutter::EncodableValue(),
      a_nullable_int_ ? flutter::EncodableValue(*a_nullable_int_)
                      : flutter::EncodableValue(),
      a_nullable_double_ ? flutter::EncodableValue(*a_nullable_double_)
                         : flutter::EncodableValue(),
      a_nullable_string_ ? flutter::EncodableValue(*a_nullable_string_)
                         : flutter::EncodableValue(),
      a_nullable_byte_array_ ? flutter::EncodableValue(*a_nullable_byte_array_)
                             : flutter::EncodableValue(),
      a_nullable4_byte_array_
          ? flutter::EncodableValue(*a_nullable4_byte_array_)
          : flutter::EncodableValue(),
      a_nullable8_byte_array_
          ? flutter::EncodableValue(*a_nullable8_byte_array_)
          : flutter::EncodableValue(),
      a_nullable_float_array_
          ? flutter::EncodableValue(*a_nullable_float_array_)
          : flutter::EncodableValue(),
      a_nullable_list_ ? flutter::EncodableValue(*a_nullable_list_)
                       : flutter::EncodableValue(),
      a_nullable_map_ ? flutter::EncodableValue(*a_nullable_map_)
                      : flutter::EncodableValue(),
      nullable_nested_list_ ? flutter::EncodableValue(*nullable_nested_list_)
                            : flutter::EncodableValue(),
      nullable_map_with_annotations_
          ? flutter::EncodableValue(*nullable_map_with_annotations_)
          : flutter::EncodableValue(),
      nullable_map_with_object_
          ? flutter::EncodableValue(*nullable_map_with_object_)
          : flutter::EncodableValue(),
      a_nullable_enum_ ? flutter::EncodableValue((int)(*a_nullable_enum_))
                       : flutter::EncodableValue(),
  };
}

AllNullableTypes::AllNullableTypes() {}

AllNullableTypes::AllNullableTypes(const flutter::EncodableList& list) {
  auto& encodable_a_nullable_bool = list[0];
  if (const bool* pointer_a_nullable_bool =
          std::get_if<bool>(&encodable_a_nullable_bool)) {
    a_nullable_bool_ = *pointer_a_nullable_bool;
  }
  auto& encodable_a_nullable_int = list[1];
  if (const int32_t* pointer_a_nullable_int =
          std::get_if<int32_t>(&encodable_a_nullable_int))
    a_nullable_int_ = *pointer_a_nullable_int;
  else if (const int64_t* pointer_a_nullable_int_64 =
               std::get_if<int64_t>(&encodable_a_nullable_int))
    a_nullable_int_ = *pointer_a_nullable_int_64;
  auto& encodable_a_nullable_double = list[2];
  if (const double* pointer_a_nullable_double =
          std::get_if<double>(&encodable_a_nullable_double)) {
    a_nullable_double_ = *pointer_a_nullable_double;
  }
  auto& encodable_a_nullable_string = list[3];
  if (const std::string* pointer_a_nullable_string =
          std::get_if<std::string>(&encodable_a_nullable_string)) {
    a_nullable_string_ = *pointer_a_nullable_string;
  }
  auto& encodable_a_nullable_byte_array = list[4];
  if (const std::vector<uint8_t>* pointer_a_nullable_byte_array =
          std::get_if<std::vector<uint8_t>>(&encodable_a_nullable_byte_array)) {
    a_nullable_byte_array_ = *pointer_a_nullable_byte_array;
  }
  auto& encodable_a_nullable4_byte_array = list[5];
  if (const std::vector<int32_t>* pointer_a_nullable4_byte_array =
          std::get_if<std::vector<int32_t>>(
              &encodable_a_nullable4_byte_array)) {
    a_nullable4_byte_array_ = *pointer_a_nullable4_byte_array;
  }
  auto& encodable_a_nullable8_byte_array = list[6];
  if (const std::vector<int64_t>* pointer_a_nullable8_byte_array =
          std::get_if<std::vector<int64_t>>(
              &encodable_a_nullable8_byte_array)) {
    a_nullable8_byte_array_ = *pointer_a_nullable8_byte_array;
  }
  auto& encodable_a_nullable_float_array = list[7];
  if (const std::vector<double>* pointer_a_nullable_float_array =
          std::get_if<std::vector<double>>(&encodable_a_nullable_float_array)) {
    a_nullable_float_array_ = *pointer_a_nullable_float_array;
  }
  auto& encodable_a_nullable_list = list[8];
  if (const flutter::EncodableList* pointer_a_nullable_list =
          std::get_if<flutter::EncodableList>(&encodable_a_nullable_list)) {
    a_nullable_list_ = *pointer_a_nullable_list;
  }
  auto& encodable_a_nullable_map = list[9];
  if (const flutter::EncodableMap* pointer_a_nullable_map =
          std::get_if<flutter::EncodableMap>(&encodable_a_nullable_map)) {
    a_nullable_map_ = *pointer_a_nullable_map;
  }
  auto& encodable_nullable_nested_list = list[10];
  if (const flutter::EncodableList* pointer_nullable_nested_list =
          std::get_if<flutter::EncodableList>(
              &encodable_nullable_nested_list)) {
    nullable_nested_list_ = *pointer_nullable_nested_list;
  }
  auto& encodable_nullable_map_with_annotations = list[11];
  if (const flutter::EncodableMap* pointer_nullable_map_with_annotations =
          std::get_if<flutter::EncodableMap>(
              &encodable_nullable_map_with_annotations)) {
    nullable_map_with_annotations_ = *pointer_nullable_map_with_annotations;
  }
  auto& encodable_nullable_map_with_object = list[12];
  if (const flutter::EncodableMap* pointer_nullable_map_with_object =
          std::get_if<flutter::EncodableMap>(
              &encodable_nullable_map_with_object)) {
    nullable_map_with_object_ = *pointer_nullable_map_with_object;
  }
  auto& encodable_a_nullable_enum = list[13];
  if (const int32_t* pointer_a_nullable_enum =
          std::get_if<int32_t>(&encodable_a_nullable_enum))
    a_nullable_enum_ = (AnEnum)*pointer_a_nullable_enum;
}

// AllNullableTypesWrapper

const AllNullableTypes& AllNullableTypesWrapper::values() const {
  return values_;
}
void AllNullableTypesWrapper::set_values(const AllNullableTypes& value_arg) {
  values_ = value_arg;
}

flutter::EncodableList AllNullableTypesWrapper::ToEncodableList() const {
  return flutter::EncodableList{
      flutter::EncodableValue(values_.ToEncodableList()),
  };
}

AllNullableTypesWrapper::AllNullableTypesWrapper() {}

AllNullableTypesWrapper::AllNullableTypesWrapper(
    const flutter::EncodableList& list) {
  auto& encodable_values = list[0];
  if (const flutter::EncodableList* pointer_values =
          std::get_if<flutter::EncodableList>(&encodable_values)) {
    values_ = AllNullableTypes(*pointer_values);
  }
}

HostIntegrationCoreApiCodecSerializer::HostIntegrationCoreApiCodecSerializer() {
}
flutter::EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
    uint8_t type, flutter::ByteStreamReader* stream) const {
  switch (type) {
    case 128:
      return flutter::CustomEncodableValue(AllNullableTypes(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 129:
      return flutter::CustomEncodableValue(AllNullableTypes(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 130:
      return flutter::CustomEncodableValue(AllNullableTypesWrapper(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 131:
      return flutter::CustomEncodableValue(
          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));

    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void HostIntegrationCoreApiCodecSerializer::WriteValue(
    const flutter::EncodableValue& value,
    flutter::ByteStreamWriter* stream) const {
  if (const flutter::CustomEncodableValue* custom_value =
          std::get_if<flutter::CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          flutter::EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(129);
      WriteValue(
          flutter::EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
      stream->WriteByte(130);
      WriteValue(flutter::EncodableValue(
                     std::any_cast<AllNullableTypesWrapper>(*custom_value)
                         .ToEncodableList()),
                 stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(131);
      WriteValue(flutter::EncodableValue(
                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
                 stream);
      return;
    }
  }
  flutter::StandardCodecSerializer::WriteValue(value, stream);
}

/// The codec used by HostIntegrationCoreApi.
const flutter::StandardMessageCodec& HostIntegrationCoreApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &HostIntegrationCoreApiCodecSerializer::GetInstance());
}

// Sets up an instance of `HostIntegrationCoreApi` to handle messages through
// the `binary_messenger`.
void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger,
                                   HostIntegrationCoreApi* api) {
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                wrapped = WrapError(output.value());
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              if (encodable_everything_arg.IsNull()) {
                reply(WrapError("everything_arg unexpectedly null."));
                return;
              }
              const auto& everything_arg = std::any_cast<const AllTypes&>(
                  std::get<flutter::CustomEncodableValue>(
                      encodable_everything_arg));
              ErrorOr<AllTypes> output = api->EchoAllTypes(everything_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(flutter::CustomEncodableValue(
                    std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              const auto* everything_arg =
                  &(std::any_cast<const AllNullableTypes&>(
                      std::get<flutter::CustomEncodableValue>(
                          encodable_everything_arg)));
              ErrorOr<std::optional<AllNullableTypes>> output =
                  api->EchoAllNullableTypes(everything_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::CustomEncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.throwError",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              std::optional<FlutterError> output = api->ThrowError();
              if (output.has_value()) {
                wrapped = WrapError(output.value());
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_an_int_arg = args.at(0);
              if (encodable_an_int_arg.IsNull()) {
                reply(WrapError("an_int_arg unexpectedly null."));
                return;
              }
              const int64_t an_int_arg = encodable_an_int_arg.LongValue();
              ErrorOr<int64_t> output = api->EchoInt(an_int_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(
                    flutter::EncodableValue(std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_double_arg = args.at(0);
              if (encodable_a_double_arg.IsNull()) {
                reply(WrapError("a_double_arg unexpectedly null."));
                return;
              }
              const auto& a_double_arg =
                  std::get<double>(encodable_a_double_arg);
              ErrorOr<double> output = api->EchoDouble(a_double_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(
                    flutter::EncodableValue(std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_bool_arg = args.at(0);
              if (encodable_a_bool_arg.IsNull()) {
                reply(WrapError("a_bool_arg unexpectedly null."));
                return;
              }
              const auto& a_bool_arg = std::get<bool>(encodable_a_bool_arg);
              ErrorOr<bool> output = api->EchoBool(a_bool_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(
                    flutter::EncodableValue(std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoString",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              ErrorOr<std::string> output = api->EchoString(a_string_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(
                    flutter::EncodableValue(std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_uint8_list_arg = args.at(0);
              if (encodable_a_uint8_list_arg.IsNull()) {
                reply(WrapError("a_uint8_list_arg unexpectedly null."));
                return;
              }
              const auto& a_uint8_list_arg =
                  std::get<std::vector<uint8_t>>(encodable_a_uint8_list_arg);
              ErrorOr<std::vector<uint8_t>> output =
                  api->EchoUint8List(a_uint8_list_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(
                    flutter::EncodableValue(std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<
        flutter::BasicMessageChannel<flutter::EncodableValue>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_wrapper_arg = args.at(0);
              if (encodable_wrapper_arg.IsNull()) {
                reply(WrapError("wrapper_arg unexpectedly null."));
                return;
              }
              const auto& wrapper_arg =
                  std::any_cast<const AllNullableTypesWrapper&>(
                      std::get<flutter::CustomEncodableValue>(
                          encodable_wrapper_arg));
              ErrorOr<std::optional<std::string>> output =
                  api->ExtractNestedNullableString(wrapper_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<
        flutter::BasicMessageChannel<flutter::EncodableValue>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_nullable_string_arg = args.at(0);
              const auto* nullable_string_arg =
                  std::get_if<std::string>(&encodable_nullable_string_arg);
              ErrorOr<AllNullableTypesWrapper> output =
                  api->CreateNestedNullableString(nullable_string_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(flutter::CustomEncodableValue(
                    std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<
        flutter::BasicMessageChannel<flutter::EncodableValue>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_bool_arg = args.at(0);
              const auto* a_nullable_bool_arg =
                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
              const auto& encodable_a_nullable_int_arg = args.at(1);
              const int64_t a_nullable_int_arg_value =
                  encodable_a_nullable_int_arg.IsNull()
                      ? 0
                      : encodable_a_nullable_int_arg.LongValue();
              const auto* a_nullable_int_arg =
                  encodable_a_nullable_int_arg.IsNull()
                      ? nullptr
                      : &a_nullable_int_arg_value;
              const auto& encodable_a_nullable_string_arg = args.at(2);
              const auto* a_nullable_string_arg =
                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
              ErrorOr<AllNullableTypes> output = api->SendMultipleNullableTypes(
                  a_nullable_bool_arg, a_nullable_int_arg,
                  a_nullable_string_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                wrapped.push_back(flutter::CustomEncodableValue(
                    std::move(output).TakeValue()));
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_int_arg = args.at(0);
              const int64_t a_nullable_int_arg_value =
                  encodable_a_nullable_int_arg.IsNull()
                      ? 0
                      : encodable_a_nullable_int_arg.LongValue();
              const auto* a_nullable_int_arg =
                  encodable_a_nullable_int_arg.IsNull()
                      ? nullptr
                      : &a_nullable_int_arg_value;
              ErrorOr<std::optional<int64_t>> output =
                  api->EchoNullableInt(a_nullable_int_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_double_arg = args.at(0);
              const auto* a_nullable_double_arg =
                  std::get_if<double>(&encodable_a_nullable_double_arg);
              ErrorOr<std::optional<double>> output =
                  api->EchoNullableDouble(a_nullable_double_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_bool_arg = args.at(0);
              const auto* a_nullable_bool_arg =
                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
              ErrorOr<std::optional<bool>> output =
                  api->EchoNullableBool(a_nullable_bool_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_string_arg = args.at(0);
              const auto* a_nullable_string_arg =
                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
              ErrorOr<std::optional<std::string>> output =
                  api->EchoNullableString(a_nullable_string_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_nullable_uint8_list_arg = args.at(0);
              const auto* a_nullable_uint8_list_arg =
                  std::get_if<std::vector<uint8_t>>(
                      &encodable_a_nullable_uint8_list_arg);
              ErrorOr<std::optional<std::vector<uint8_t>>> output =
                  api->EchoNullableUint8List(a_nullable_uint8_list_arg);
              if (output.has_error()) {
                wrapped = WrapError(output.error());
              } else {
                auto output_optional = std::move(output).TakeValue();
                if (output_optional) {
                  wrapped.push_back(flutter::EncodableValue(
                      std::move(output_optional).value()));
                } else {
                  wrapped.push_back(flutter::EncodableValue());
                }
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              api->NoopAsync(
                  [&wrapped, &reply](std::optional<FlutterError>&& output) {
                    if (output.has_value()) {
                      wrapped = WrapError(output.value());
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(wrapped);
                  });
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
              reply(wrapped);
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              api->EchoAsyncString(
                  a_string_arg,
                  [&wrapped, &reply](ErrorOr<std::string>&& output) {
                    if (output.has_error()) {
                      wrapped = WrapError(output.error());
                    } else {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output).TakeValue()));
                    }
                    reply(wrapped);
                  });
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
              reply(wrapped);
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              api->CallFlutterNoop(
                  [&wrapped, &reply](std::optional<FlutterError>&& output) {
                    if (output.has_value()) {
                      wrapped = WrapError(output.value());
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(wrapped);
                  });
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
              reply(wrapped);
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger,
            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              api->CallFlutterEchoString(
                  a_string_arg,
                  [&wrapped, &reply](ErrorOr<std::string>&& output) {
                    if (output.has_error()) {
                      wrapped = WrapError(output.error());
                    } else {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output).TakeValue()));
                    }
                    reply(wrapped);
                  });
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
              reply(wrapped);
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

flutter::EncodableList HostIntegrationCoreApi::WrapError(
    std::string_view error_message) {
  return flutter::EncodableList(
      {flutter::EncodableValue(std::string(error_message)),
       flutter::EncodableValue("Error"), flutter::EncodableValue()});
}
flutter::EncodableList HostIntegrationCoreApi::WrapError(
    const FlutterError& error) {
  return flutter::EncodableList({flutter::EncodableValue(error.message()),
                                 flutter::EncodableValue(error.code()),
                                 error.details()});
}

FlutterIntegrationCoreApiCodecSerializer::
    FlutterIntegrationCoreApiCodecSerializer() {}
flutter::EncodableValue
FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType(
    uint8_t type, flutter::ByteStreamReader* stream) const {
  switch (type) {
    case 128:
      return flutter::CustomEncodableValue(AllNullableTypes(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 129:
      return flutter::CustomEncodableValue(
          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));

    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void FlutterIntegrationCoreApiCodecSerializer::WriteValue(
    const flutter::EncodableValue& value,
    flutter::ByteStreamWriter* stream) const {
  if (const flutter::CustomEncodableValue* custom_value =
          std::get_if<flutter::CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          flutter::EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(129);
      WriteValue(flutter::EncodableValue(
                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
                 stream);
      return;
    }
  }
  flutter::StandardCodecSerializer::WriteValue(value, stream);
}

// Generated class from Pigeon that represents Flutter messages that can be
// called from C++.
FlutterIntegrationCoreApi::FlutterIntegrationCoreApi(
    flutter::BinaryMessenger* binary_messenger) {
  this->binary_messenger_ = binary_messenger;
}

const flutter::StandardMessageCodec& FlutterIntegrationCoreApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &FlutterIntegrationCoreApiCodecSerializer::GetInstance());
}

void FlutterIntegrationCoreApi::noop(std::function<void(void)>&& callback) {
  auto channel =
      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
          binary_messenger_,
          "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", &GetCodec());
  channel->Send(
      flutter::EncodableValue(),
      [callback](const uint8_t* reply, size_t reply_size) { callback(); });
}
void FlutterIntegrationCoreApi::echoAllTypes(
    const AllTypes& everything_arg,
    std::function<void(const AllTypes&)>&& callback) {
  auto channel =
      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
          binary_messenger_,
          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes",
          &GetCodec());
  channel->Send(
      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
      [callback](const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<flutter::EncodableValue> decoded_reply =
            GetCodec().DecodeMessage(reply, reply_size);
        flutter::EncodableValue args =
            *(flutter::EncodableValue*)(decoded_reply.release());
        AllTypes output{};
        if (const flutter::EncodableList* pointer_output =
                std::get_if<flutter::EncodableList>(&args)) {
          output = AllTypes(*pointer_output);
        }
        callback(output);
      });
}
void FlutterIntegrationCoreApi::echoAllNullableTypes(
    const AllNullableTypes& everything_arg,
    std::function<void(const AllNullableTypes&)>&& callback) {
  auto channel =
      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
          binary_messenger_,
          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
          &GetCodec());
  channel->Send(
      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
      [callback](const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<flutter::EncodableValue> decoded_reply =
            GetCodec().DecodeMessage(reply, reply_size);
        flutter::EncodableValue args =
            *(flutter::EncodableValue*)(decoded_reply.release());
        AllNullableTypes output{};
        if (const flutter::EncodableList* pointer_output =
                std::get_if<flutter::EncodableList>(&args)) {
          output = AllNullableTypes(*pointer_output);
        }
        callback(output);
      });
}
void FlutterIntegrationCoreApi::echoString(
    const std::string& a_string_arg,
    std::function<void(const std::string&)>&& callback) {
  auto channel =
      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
          binary_messenger_,
          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString",
          &GetCodec());
  channel->Send(
      flutter::EncodableList{flutter::CustomEncodableValue(a_string_arg)},
      [callback](const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<flutter::EncodableValue> decoded_reply =
            GetCodec().DecodeMessage(reply, reply_size);
        flutter::EncodableValue args =
            *(flutter::EncodableValue*)(decoded_reply.release());
        std::string output{};
        if (const std::string* pointer_output =
                std::get_if<std::string>(&args)) {
          output = *pointer_output;
        }
        callback(output);
      });
}
/// The codec used by HostTrivialApi.
const flutter::StandardMessageCodec& HostTrivialApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &flutter::StandardCodecSerializer::GetInstance());
}

// Sets up an instance of `HostTrivialApi` to handle messages through the
// `binary_messenger`.
void HostTrivialApi::SetUp(flutter::BinaryMessenger* binary_messenger,
                           HostTrivialApi* api) {
  {
    auto channel =
        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
            binary_messenger, "dev.flutter.pigeon.HostTrivialApi.noop",
            &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            flutter::EncodableList wrapped;
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                wrapped = WrapError(output.value());
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
            } catch (const std::exception& exception) {
              wrapped = WrapError(exception.what());
            }
            reply(wrapped);
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

flutter::EncodableList HostTrivialApi::WrapError(
    std::string_view error_message) {
  return flutter::EncodableList(
      {flutter::EncodableValue(std::string(error_message)),
       flutter::EncodableValue("Error"), flutter::EncodableValue()});
}
flutter::EncodableList HostTrivialApi::WrapError(const FlutterError& error) {
  return flutter::EncodableList({flutter::EncodableValue(error.message()),
                                 flutter::EncodableValue(error.code()),
                                 error.details()});
}

}  // namespace core_tests_pigeontest
