// services/device/public/mojom/serial.mojom-blink.cc is auto generated by mojom_bindings_generator.py, do not edit

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif

#include "services/device/public/mojom/serial.mojom-blink.h"

#include <math.h>
#include <stdint.h>
#include <utility>

#include "base/debug/alias.h"
#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "mojo/public/cpp/bindings/features.h"
#include "mojo/public/cpp/bindings/lib/default_construct_tag_internal.h"
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.h"
#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/cpp/bindings/urgent_message_scope.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"

#include "services/device/public/mojom/serial.mojom-params-data.h"
#include "services/device/public/mojom/serial.mojom-shared-message-ids.h"

#include "services/device/public/mojom/serial.mojom-blink-import-headers.h"
#include "services/device/public/mojom/serial.mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"


namespace device::mojom::blink {
SerialPortInfo::SerialPortInfo()
    : token(),
      path(),
      type(SerialPortType::PLATFORM_SERIAL),
      device_instance_id(),
      vendor_id(),
      has_vendor_id(false),
      product_id(),
      has_product_id(false),
      bluetooth_service_class_id(),
      display_name(),
      serial_number(),
      connected(true) {}

SerialPortInfo::SerialPortInfo(
    const ::base::UnguessableToken& token_in,
    const ::base::FilePath& path_in,
    SerialPortType type_in,
    const WTF::String& device_instance_id_in,
    uint16_t vendor_id_in,
    bool has_vendor_id_in,
    uint16_t product_id_in,
    bool has_product_id_in,
    ::bluetooth::mojom::blink::UUIDPtr bluetooth_service_class_id_in,
    const WTF::String& display_name_in,
    const WTF::String& serial_number_in,
    bool connected_in)
    : token(std::move(token_in)),
      path(std::move(path_in)),
      type(std::move(type_in)),
      device_instance_id(std::move(device_instance_id_in)),
      vendor_id(std::move(vendor_id_in)),
      has_vendor_id(std::move(has_vendor_id_in)),
      product_id(std::move(product_id_in)),
      has_product_id(std::move(has_product_id_in)),
      bluetooth_service_class_id(std::move(bluetooth_service_class_id_in)),
      display_name(std::move(display_name_in)),
      serial_number(std::move(serial_number_in)),
      connected(std::move(connected_in)) {}

SerialPortInfo::~SerialPortInfo() = default;

void SerialPortInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "token"), this->token,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const ::base::UnguessableToken&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "path"), this->path,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const ::base::FilePath&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "type"), this->type,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialPortType>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "device_instance_id"), this->device_instance_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const WTF::String&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "vendor_id"), this->vendor_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_vendor_id"), this->has_vendor_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "product_id"), this->product_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint16_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_product_id"), this->has_product_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "bluetooth_service_class_id"), this->bluetooth_service_class_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type ::bluetooth::mojom::blink::UUIDPtr>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "display_name"), this->display_name,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const WTF::String&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "serial_number"), this->serial_number,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type const WTF::String&>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "connected"), this->connected,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool SerialPortInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
SerialConnectionOptions::SerialConnectionOptions()
    : bitrate(0U),
      data_bits(SerialDataBits::NONE),
      parity_bit(SerialParityBit::NONE),
      stop_bits(SerialStopBits::NONE),
      cts_flow_control(),
      has_cts_flow_control(false) {}

SerialConnectionOptions::SerialConnectionOptions(
    uint32_t bitrate_in,
    SerialDataBits data_bits_in,
    SerialParityBit parity_bit_in,
    SerialStopBits stop_bits_in,
    bool cts_flow_control_in,
    bool has_cts_flow_control_in)
    : bitrate(std::move(bitrate_in)),
      data_bits(std::move(data_bits_in)),
      parity_bit(std::move(parity_bit_in)),
      stop_bits(std::move(stop_bits_in)),
      cts_flow_control(std::move(cts_flow_control_in)),
      has_cts_flow_control(std::move(has_cts_flow_control_in)) {}

SerialConnectionOptions::~SerialConnectionOptions() = default;
size_t SerialConnectionOptions::Hash(size_t seed) const {
  seed = mojo::internal::WTFHash(seed, this->bitrate);
  seed = mojo::internal::WTFHash(seed, this->data_bits);
  seed = mojo::internal::WTFHash(seed, this->parity_bit);
  seed = mojo::internal::WTFHash(seed, this->stop_bits);
  seed = mojo::internal::WTFHash(seed, this->cts_flow_control);
  seed = mojo::internal::WTFHash(seed, this->has_cts_flow_control);
  return seed;
}

void SerialConnectionOptions::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "bitrate"), this->bitrate,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "data_bits"), this->data_bits,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialDataBits>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "parity_bit"), this->parity_bit,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialParityBit>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "stop_bits"), this->stop_bits,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialStopBits>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "cts_flow_control"), this->cts_flow_control,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_cts_flow_control"), this->has_cts_flow_control,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool SerialConnectionOptions::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
SerialConnectionInfo::SerialConnectionInfo()
    : bitrate(0U),
      data_bits(SerialDataBits::NONE),
      parity_bit(SerialParityBit::NONE),
      stop_bits(SerialStopBits::NONE),
      cts_flow_control() {}

SerialConnectionInfo::SerialConnectionInfo(
    uint32_t bitrate_in,
    SerialDataBits data_bits_in,
    SerialParityBit parity_bit_in,
    SerialStopBits stop_bits_in,
    bool cts_flow_control_in)
    : bitrate(std::move(bitrate_in)),
      data_bits(std::move(data_bits_in)),
      parity_bit(std::move(parity_bit_in)),
      stop_bits(std::move(stop_bits_in)),
      cts_flow_control(std::move(cts_flow_control_in)) {}

SerialConnectionInfo::~SerialConnectionInfo() = default;
size_t SerialConnectionInfo::Hash(size_t seed) const {
  seed = mojo::internal::WTFHash(seed, this->bitrate);
  seed = mojo::internal::WTFHash(seed, this->data_bits);
  seed = mojo::internal::WTFHash(seed, this->parity_bit);
  seed = mojo::internal::WTFHash(seed, this->stop_bits);
  seed = mojo::internal::WTFHash(seed, this->cts_flow_control);
  return seed;
}

void SerialConnectionInfo::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "bitrate"), this->bitrate,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type uint32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "data_bits"), this->data_bits,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialDataBits>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "parity_bit"), this->parity_bit,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialParityBit>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "stop_bits"), this->stop_bits,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type SerialStopBits>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "cts_flow_control"), this->cts_flow_control,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool SerialConnectionInfo::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
SerialHostControlSignals::SerialHostControlSignals()
    : dtr(),
      has_dtr(false),
      rts(),
      has_rts(false),
      brk(),
      has_brk(false) {}

SerialHostControlSignals::SerialHostControlSignals(
    bool dtr_in,
    bool has_dtr_in,
    bool rts_in,
    bool has_rts_in,
    bool brk_in,
    bool has_brk_in)
    : dtr(std::move(dtr_in)),
      has_dtr(std::move(has_dtr_in)),
      rts(std::move(rts_in)),
      has_rts(std::move(has_rts_in)),
      brk(std::move(brk_in)),
      has_brk(std::move(has_brk_in)) {}

SerialHostControlSignals::~SerialHostControlSignals() = default;
size_t SerialHostControlSignals::Hash(size_t seed) const {
  seed = mojo::internal::WTFHash(seed, this->dtr);
  seed = mojo::internal::WTFHash(seed, this->has_dtr);
  seed = mojo::internal::WTFHash(seed, this->rts);
  seed = mojo::internal::WTFHash(seed, this->has_rts);
  seed = mojo::internal::WTFHash(seed, this->brk);
  seed = mojo::internal::WTFHash(seed, this->has_brk);
  return seed;
}

void SerialHostControlSignals::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "dtr"), this->dtr,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_dtr"), this->has_dtr,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "rts"), this->rts,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_rts"), this->has_rts,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "brk"), this->brk,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "has_brk"), this->has_brk,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool SerialHostControlSignals::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
SerialPortControlSignals::SerialPortControlSignals()
    : dcd(),
      cts(),
      ri(),
      dsr() {}

SerialPortControlSignals::SerialPortControlSignals(
    bool dcd_in,
    bool cts_in,
    bool ri_in,
    bool dsr_in)
    : dcd(std::move(dcd_in)),
      cts(std::move(cts_in)),
      ri(std::move(ri_in)),
      dsr(std::move(dsr_in)) {}

SerialPortControlSignals::~SerialPortControlSignals() = default;
size_t SerialPortControlSignals::Hash(size_t seed) const {
  seed = mojo::internal::WTFHash(seed, this->dcd);
  seed = mojo::internal::WTFHash(seed, this->cts);
  seed = mojo::internal::WTFHash(seed, this->ri);
  seed = mojo::internal::WTFHash(seed, this->dsr);
  return seed;
}

void SerialPortControlSignals::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "dcd"), this->dcd,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "cts"), this->cts,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "ri"), this->ri,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "dsr"), this->dsr,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool SerialPortControlSignals::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
const char SerialPortManager::Name_[] = "device.mojom.SerialPortManager";

SerialPortManager::IPCStableHashFunction SerialPortManager::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::SerialPortManager>(message.name())) {
    case messages::SerialPortManager::kSetClient: {
      return &SerialPortManager::SetClient_Sym::IPCStableHash;
    }
    case messages::SerialPortManager::kGetDevices: {
      return &SerialPortManager::GetDevices_Sym::IPCStableHash;
    }
    case messages::SerialPortManager::kOpenPort: {
      return &SerialPortManager::OpenPort_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* SerialPortManager::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (static_cast<messages::SerialPortManager>(message.name())) {
      case messages::SerialPortManager::kSetClient:
            return "Receive device::mojom::SerialPortManager::SetClient";
      case messages::SerialPortManager::kGetDevices:
            return "Receive device::mojom::SerialPortManager::GetDevices";
      case messages::SerialPortManager::kOpenPort:
            return "Receive device::mojom::SerialPortManager::OpenPort";
    }
  } else {
    switch (static_cast<messages::SerialPortManager>(message.name())) {
      case messages::SerialPortManager::kSetClient:
            return "Receive reply device::mojom::SerialPortManager::SetClient";
      case messages::SerialPortManager::kGetDevices:
            return "Receive reply device::mojom::SerialPortManager::GetDevices";
      case messages::SerialPortManager::kOpenPort:
            return "Receive reply device::mojom::SerialPortManager::OpenPort";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
uint32_t SerialPortManager::SetClient_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManager::SetClient");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPortManager::GetDevices_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManager::GetDevices");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPortManager::OpenPort_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManager::OpenPort");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

class SerialPortManager_GetDevices_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPortManager_GetDevices_ForwardToCallback(
      SerialPortManager::GetDevicesCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPortManager_GetDevices_ForwardToCallback(const SerialPortManager_GetDevices_ForwardToCallback&) = delete;
  SerialPortManager_GetDevices_ForwardToCallback& operator=(const SerialPortManager_GetDevices_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPortManager::GetDevicesCallback callback_;
};

class SerialPortManager_OpenPort_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPortManager_OpenPort_ForwardToCallback(
      SerialPortManager::OpenPortCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPortManager_OpenPort_ForwardToCallback(const SerialPortManager_OpenPort_ForwardToCallback&) = delete;
  SerialPortManager_OpenPort_ForwardToCallback& operator=(const SerialPortManager_OpenPort_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPortManager::OpenPortCallback callback_;
};

SerialPortManagerProxy::SerialPortManagerProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void SerialPortManagerProxy::SetClient(
    ::mojo::PendingRemote<SerialPortManagerClient> in_client) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortManager::SetClient", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("client"), in_client,
                        "<value of type ::mojo::PendingRemote<SerialPortManagerClient>>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManager::kSetClient), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManager_SetClient_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::device::mojom::SerialPortManagerClientInterfaceBase>>(
      in_client, &params->client, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->client),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid client in SerialPortManager.SetClient request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManager::Name_);
  message.set_method_name("SetClient");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortManagerProxy::GetDevices(
    GetDevicesCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::SerialPortManager::GetDevices");
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManager::kGetDevices), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManager_GetDevices_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManager::Name_);
  message.set_method_name("GetDevices");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPortManager_GetDevices_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortManagerProxy::OpenPort(
    const ::base::UnguessableToken& in_token, bool in_use_alternate_path, SerialConnectionOptionsPtr in_options, ::mojo::PendingRemote<SerialPortClient> in_client, ::mojo::PendingRemote<SerialPortConnectionWatcher> in_watcher, OpenPortCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortManager::OpenPort", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("token"), in_token,
                        "<value of type const ::base::UnguessableToken&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("use_alternate_path"), in_use_alternate_path,
                        "<value of type bool>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("options"), in_options,
                        "<value of type SerialConnectionOptionsPtr>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("client"), in_client,
                        "<value of type ::mojo::PendingRemote<SerialPortClient>>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("watcher"), in_watcher,
                        "<value of type ::mojo::PendingRemote<SerialPortConnectionWatcher>>");
   });
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManager::kOpenPort), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManager_OpenPort_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->token)::BaseType> token_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::UnguessableTokenDataView>(
      in_token, token_fragment);
  params->token.Set(
      token_fragment.is_null() ? nullptr : token_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->token.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null token in SerialPortManager.OpenPort request");
  params->use_alternate_path = in_use_alternate_path;
  mojo::internal::MessageFragment<
      typename decltype(params->options)::BaseType> options_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialConnectionOptionsDataView>(
      in_options, options_fragment);
  params->options.Set(
      options_fragment.is_null() ? nullptr : options_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->options.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null options in SerialPortManager.OpenPort request");
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::device::mojom::SerialPortClientInterfaceBase>>(
      in_client, &params->client, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->client),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid client in SerialPortManager.OpenPort request");
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::device::mojom::SerialPortConnectionWatcherInterfaceBase>>(
      in_watcher, &params->watcher, &params.message());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManager::Name_);
  message.set_method_name("OpenPort");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPortManager_OpenPort_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}
class SerialPortManager_GetDevices_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPortManager::GetDevicesCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPortManager_GetDevices_ProxyToResponder> proxy(
        new SerialPortManager_GetDevices_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPortManager_GetDevices_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPortManager_GetDevices_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPortManager_GetDevices_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPortManager::GetDevicesCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      WTF::Vector<SerialPortInfoPtr> in_devices);
};

bool SerialPortManager_GetDevices_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPortManager_GetDevices_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPortManager_GetDevices_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPortManager.1
  bool success = true;
  WTF::Vector<SerialPortInfoPtr> p_devices{};
  SerialPortManager_GetDevices_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadDevices(&p_devices))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPortManager::Name_, 1, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_devices));
  return true;
}

void SerialPortManager_GetDevices_ProxyToResponder::Run(
    WTF::Vector<SerialPortInfoPtr> in_devices) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPortManager::GetDevices", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("devices"), in_devices,
                        "<value of type WTF::Vector<SerialPortInfoPtr>>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManager::kGetDevices), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManager_GetDevices_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->devices)::BaseType>
      devices_fragment(params.message());
  constexpr const mojo::internal::ContainerValidateParams& devices_validate_params =
      mojo::internal::GetArrayValidator<0, false, nullptr>();
  mojo::internal::Serialize<mojo::ArrayDataView<::device::mojom::SerialPortInfoDataView>>(
      in_devices, devices_fragment, &devices_validate_params);
  params->devices.Set(
      devices_fragment.is_null() ? nullptr : devices_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->devices.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null devices in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManager::Name_);
  message.set_method_name("GetDevices");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPortManager_OpenPort_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPortManager::OpenPortCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPortManager_OpenPort_ProxyToResponder> proxy(
        new SerialPortManager_OpenPort_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPortManager_OpenPort_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPortManager_OpenPort_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPortManager_OpenPort_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPortManager::OpenPortCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      ::mojo::PendingRemote<SerialPort> in_port);
};

bool SerialPortManager_OpenPort_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPortManager_OpenPort_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPortManager_OpenPort_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPortManager.2
  bool success = true;
  ::mojo::PendingRemote<SerialPort> p_port{};
  SerialPortManager_OpenPort_ResponseParamsDataView input_data_view(params, message);
  
  if (success) {
    p_port =
        input_data_view.TakePort<decltype(p_port)>();
  }
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPortManager::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_port));
  return true;
}

void SerialPortManager_OpenPort_ProxyToResponder::Run(
    ::mojo::PendingRemote<SerialPort> in_port) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPortManager::OpenPort", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("port"), in_port,
                        "<value of type ::mojo::PendingRemote<SerialPort>>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManager::kOpenPort), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManager_OpenPort_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::device::mojom::SerialPortInterfaceBase>>(
      in_port, &params->port, &params.message());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManager::Name_);
  message.set_method_name("OpenPort");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}

// static
bool SerialPortManagerStubDispatch::Accept(
    SerialPortManager* impl,
    mojo::Message* message) {
  switch (static_cast<messages::SerialPortManager>(message->header()->name)) {
    case messages::SerialPortManager::kSetClient: {
      DCHECK(message->is_serialized());
      internal::SerialPortManager_SetClient_Params_Data* params =
          reinterpret_cast<internal::SerialPortManager_SetClient_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortManager.0
      bool success = true;
      ::mojo::PendingRemote<SerialPortManagerClient> p_client{};
      SerialPortManager_SetClient_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_client =
            input_data_view.TakeClient<decltype(p_client)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManager::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetClient(        
        std::move(p_client));
      return true;
    }
    case messages::SerialPortManager::kGetDevices: {
      break;
    }
    case messages::SerialPortManager::kOpenPort: {
      break;
    }
  }
  return false;
}

// static
bool SerialPortManagerStubDispatch::AcceptWithResponder(
    SerialPortManager* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (static_cast<messages::SerialPortManager>(message->header()->name)) {
    case messages::SerialPortManager::kSetClient: {
      break;
    }
    case messages::SerialPortManager::kGetDevices: {
      internal::SerialPortManager_GetDevices_Params_Data* params =
          reinterpret_cast<
              internal::SerialPortManager_GetDevices_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPortManager.1
      bool success = true;
      SerialPortManager_GetDevices_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManager::Name_, 1, false);
        return false;
      }
      SerialPortManager::GetDevicesCallback callback =
          SerialPortManager_GetDevices_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetDevices(std::move(callback));
      return true;
    }
    case messages::SerialPortManager::kOpenPort: {
      internal::SerialPortManager_OpenPort_Params_Data* params =
          reinterpret_cast<
              internal::SerialPortManager_OpenPort_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPortManager.2
      bool success = true;
      ::base::UnguessableToken p_token{};
      bool p_use_alternate_path{};
      SerialConnectionOptionsPtr p_options{};
      ::mojo::PendingRemote<SerialPortClient> p_client{};
      ::mojo::PendingRemote<SerialPortConnectionWatcher> p_watcher{};
      SerialPortManager_OpenPort_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadToken(&p_token))
        success = false;
      if (success)
        p_use_alternate_path = input_data_view.use_alternate_path();
      if (success && !input_data_view.ReadOptions(&p_options))
        success = false;
      if (success) {
        p_client =
            input_data_view.TakeClient<decltype(p_client)>();
      }
      if (success) {
        p_watcher =
            input_data_view.TakeWatcher<decltype(p_watcher)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManager::Name_, 2, false);
        return false;
      }
      SerialPortManager::OpenPortCallback callback =
          SerialPortManager_OpenPort_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OpenPort(        
        std::move(p_token), 
        std::move(p_use_alternate_path), 
        std::move(p_options), 
        std::move(p_client), 
        std::move(p_watcher), std::move(callback));
      return true;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kSerialPortManagerValidationInfo[] = {
    { &internal::SerialPortManager_SetClient_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPortManager_GetDevices_Params_Data::Validate,
     &internal::SerialPortManager_GetDevices_ResponseParams_Data::Validate},
    { &internal::SerialPortManager_OpenPort_Params_Data::Validate,
     &internal::SerialPortManager_OpenPort_ResponseParams_Data::Validate},
};

bool SerialPortManagerRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPortManager::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kSerialPortManagerValidationInfo);
}

bool SerialPortManagerResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPortManager::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kSerialPortManagerValidationInfo);
}
const char SerialPortManagerClient::Name_[] = "device.mojom.SerialPortManagerClient";

SerialPortManagerClient::IPCStableHashFunction SerialPortManagerClient::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::SerialPortManagerClient>(message.name())) {
    case messages::SerialPortManagerClient::kOnPortAdded: {
      return &SerialPortManagerClient::OnPortAdded_Sym::IPCStableHash;
    }
    case messages::SerialPortManagerClient::kOnPortRemoved: {
      return &SerialPortManagerClient::OnPortRemoved_Sym::IPCStableHash;
    }
    case messages::SerialPortManagerClient::kOnPortConnectedStateChanged: {
      return &SerialPortManagerClient::OnPortConnectedStateChanged_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* SerialPortManagerClient::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (static_cast<messages::SerialPortManagerClient>(message.name())) {
      case messages::SerialPortManagerClient::kOnPortAdded:
            return "Receive device::mojom::SerialPortManagerClient::OnPortAdded";
      case messages::SerialPortManagerClient::kOnPortRemoved:
            return "Receive device::mojom::SerialPortManagerClient::OnPortRemoved";
      case messages::SerialPortManagerClient::kOnPortConnectedStateChanged:
            return "Receive device::mojom::SerialPortManagerClient::OnPortConnectedStateChanged";
    }
  } else {
    switch (static_cast<messages::SerialPortManagerClient>(message.name())) {
      case messages::SerialPortManagerClient::kOnPortAdded:
            return "Receive reply device::mojom::SerialPortManagerClient::OnPortAdded";
      case messages::SerialPortManagerClient::kOnPortRemoved:
            return "Receive reply device::mojom::SerialPortManagerClient::OnPortRemoved";
      case messages::SerialPortManagerClient::kOnPortConnectedStateChanged:
            return "Receive reply device::mojom::SerialPortManagerClient::OnPortConnectedStateChanged";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
uint32_t SerialPortManagerClient::OnPortAdded_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManagerClient::OnPortAdded");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPortManagerClient::OnPortRemoved_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManagerClient::OnPortRemoved");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPortManagerClient::OnPortConnectedStateChanged_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortManagerClient::OnPortConnectedStateChanged");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

SerialPortManagerClientProxy::SerialPortManagerClientProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void SerialPortManagerClientProxy::OnPortAdded(
    SerialPortInfoPtr in_port_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortManagerClient::OnPortAdded", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("port_info"), in_port_info,
                        "<value of type SerialPortInfoPtr>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManagerClient::kOnPortAdded), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManagerClient_OnPortAdded_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->port_info)::BaseType> port_info_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialPortInfoDataView>(
      in_port_info, port_info_fragment);
  params->port_info.Set(
      port_info_fragment.is_null() ? nullptr : port_info_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->port_info.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null port_info in SerialPortManagerClient.OnPortAdded request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManagerClient::Name_);
  message.set_method_name("OnPortAdded");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortManagerClientProxy::OnPortRemoved(
    SerialPortInfoPtr in_port_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortManagerClient::OnPortRemoved", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("port_info"), in_port_info,
                        "<value of type SerialPortInfoPtr>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManagerClient::kOnPortRemoved), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManagerClient_OnPortRemoved_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->port_info)::BaseType> port_info_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialPortInfoDataView>(
      in_port_info, port_info_fragment);
  params->port_info.Set(
      port_info_fragment.is_null() ? nullptr : port_info_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->port_info.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null port_info in SerialPortManagerClient.OnPortRemoved request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManagerClient::Name_);
  message.set_method_name("OnPortRemoved");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortManagerClientProxy::OnPortConnectedStateChanged(
    SerialPortInfoPtr in_port_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortManagerClient::OnPortConnectedStateChanged", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("port_info"), in_port_info,
                        "<value of type SerialPortInfoPtr>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortManagerClient::kOnPortConnectedStateChanged), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortManagerClient_OnPortConnectedStateChanged_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->port_info)::BaseType> port_info_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialPortInfoDataView>(
      in_port_info, port_info_fragment);
  params->port_info.Set(
      port_info_fragment.is_null() ? nullptr : port_info_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->port_info.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null port_info in SerialPortManagerClient.OnPortConnectedStateChanged request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortManagerClient::Name_);
  message.set_method_name("OnPortConnectedStateChanged");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

// static
bool SerialPortManagerClientStubDispatch::Accept(
    SerialPortManagerClient* impl,
    mojo::Message* message) {
  switch (static_cast<messages::SerialPortManagerClient>(message->header()->name)) {
    case messages::SerialPortManagerClient::kOnPortAdded: {
      DCHECK(message->is_serialized());
      internal::SerialPortManagerClient_OnPortAdded_Params_Data* params =
          reinterpret_cast<internal::SerialPortManagerClient_OnPortAdded_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortManagerClient.0
      bool success = true;
      SerialPortInfoPtr p_port_info{};
      SerialPortManagerClient_OnPortAdded_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPortInfo(&p_port_info))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManagerClient::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnPortAdded(        
        std::move(p_port_info));
      return true;
    }
    case messages::SerialPortManagerClient::kOnPortRemoved: {
      DCHECK(message->is_serialized());
      internal::SerialPortManagerClient_OnPortRemoved_Params_Data* params =
          reinterpret_cast<internal::SerialPortManagerClient_OnPortRemoved_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortManagerClient.1
      bool success = true;
      SerialPortInfoPtr p_port_info{};
      SerialPortManagerClient_OnPortRemoved_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPortInfo(&p_port_info))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManagerClient::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnPortRemoved(        
        std::move(p_port_info));
      return true;
    }
    case messages::SerialPortManagerClient::kOnPortConnectedStateChanged: {
      DCHECK(message->is_serialized());
      internal::SerialPortManagerClient_OnPortConnectedStateChanged_Params_Data* params =
          reinterpret_cast<internal::SerialPortManagerClient_OnPortConnectedStateChanged_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortManagerClient.2
      bool success = true;
      SerialPortInfoPtr p_port_info{};
      SerialPortManagerClient_OnPortConnectedStateChanged_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPortInfo(&p_port_info))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortManagerClient::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnPortConnectedStateChanged(        
        std::move(p_port_info));
      return true;
    }
  }
  return false;
}

// static
bool SerialPortManagerClientStubDispatch::AcceptWithResponder(
    SerialPortManagerClient* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (static_cast<messages::SerialPortManagerClient>(message->header()->name)) {
    case messages::SerialPortManagerClient::kOnPortAdded: {
      break;
    }
    case messages::SerialPortManagerClient::kOnPortRemoved: {
      break;
    }
    case messages::SerialPortManagerClient::kOnPortConnectedStateChanged: {
      break;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kSerialPortManagerClientValidationInfo[] = {
    { &internal::SerialPortManagerClient_OnPortAdded_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPortManagerClient_OnPortRemoved_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPortManagerClient_OnPortConnectedStateChanged_Params_Data::Validate,
     nullptr /* no response */},
};

bool SerialPortManagerClientRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPortManagerClient::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kSerialPortManagerClientValidationInfo);
}

const char SerialPort::Name_[] = "device.mojom.SerialPort";

SerialPort::IPCStableHashFunction SerialPort::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::SerialPort>(message.name())) {
    case messages::SerialPort::kStartWriting: {
      return &SerialPort::StartWriting_Sym::IPCStableHash;
    }
    case messages::SerialPort::kStartReading: {
      return &SerialPort::StartReading_Sym::IPCStableHash;
    }
    case messages::SerialPort::kFlush: {
      return &SerialPort::Flush_Sym::IPCStableHash;
    }
    case messages::SerialPort::kDrain: {
      return &SerialPort::Drain_Sym::IPCStableHash;
    }
    case messages::SerialPort::kGetControlSignals: {
      return &SerialPort::GetControlSignals_Sym::IPCStableHash;
    }
    case messages::SerialPort::kSetControlSignals: {
      return &SerialPort::SetControlSignals_Sym::IPCStableHash;
    }
    case messages::SerialPort::kConfigurePort: {
      return &SerialPort::ConfigurePort_Sym::IPCStableHash;
    }
    case messages::SerialPort::kGetPortInfo: {
      return &SerialPort::GetPortInfo_Sym::IPCStableHash;
    }
    case messages::SerialPort::kClose: {
      return &SerialPort::Close_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* SerialPort::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (static_cast<messages::SerialPort>(message.name())) {
      case messages::SerialPort::kStartWriting:
            return "Receive device::mojom::SerialPort::StartWriting";
      case messages::SerialPort::kStartReading:
            return "Receive device::mojom::SerialPort::StartReading";
      case messages::SerialPort::kFlush:
            return "Receive device::mojom::SerialPort::Flush";
      case messages::SerialPort::kDrain:
            return "Receive device::mojom::SerialPort::Drain";
      case messages::SerialPort::kGetControlSignals:
            return "Receive device::mojom::SerialPort::GetControlSignals";
      case messages::SerialPort::kSetControlSignals:
            return "Receive device::mojom::SerialPort::SetControlSignals";
      case messages::SerialPort::kConfigurePort:
            return "Receive device::mojom::SerialPort::ConfigurePort";
      case messages::SerialPort::kGetPortInfo:
            return "Receive device::mojom::SerialPort::GetPortInfo";
      case messages::SerialPort::kClose:
            return "Receive device::mojom::SerialPort::Close";
    }
  } else {
    switch (static_cast<messages::SerialPort>(message.name())) {
      case messages::SerialPort::kStartWriting:
            return "Receive reply device::mojom::SerialPort::StartWriting";
      case messages::SerialPort::kStartReading:
            return "Receive reply device::mojom::SerialPort::StartReading";
      case messages::SerialPort::kFlush:
            return "Receive reply device::mojom::SerialPort::Flush";
      case messages::SerialPort::kDrain:
            return "Receive reply device::mojom::SerialPort::Drain";
      case messages::SerialPort::kGetControlSignals:
            return "Receive reply device::mojom::SerialPort::GetControlSignals";
      case messages::SerialPort::kSetControlSignals:
            return "Receive reply device::mojom::SerialPort::SetControlSignals";
      case messages::SerialPort::kConfigurePort:
            return "Receive reply device::mojom::SerialPort::ConfigurePort";
      case messages::SerialPort::kGetPortInfo:
            return "Receive reply device::mojom::SerialPort::GetPortInfo";
      case messages::SerialPort::kClose:
            return "Receive reply device::mojom::SerialPort::Close";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
uint32_t SerialPort::StartWriting_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::StartWriting");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::StartReading_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::StartReading");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::Flush_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::Flush");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::Drain_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::Drain");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::GetControlSignals_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::GetControlSignals");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::SetControlSignals_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::SetControlSignals");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::ConfigurePort_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::ConfigurePort");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::GetPortInfo_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::GetPortInfo");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPort::Close_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPort::Close");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

class SerialPort_Flush_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_Flush_ForwardToCallback(
      SerialPort::FlushCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_Flush_ForwardToCallback(const SerialPort_Flush_ForwardToCallback&) = delete;
  SerialPort_Flush_ForwardToCallback& operator=(const SerialPort_Flush_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::FlushCallback callback_;
};

class SerialPort_Drain_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_Drain_ForwardToCallback(
      SerialPort::DrainCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_Drain_ForwardToCallback(const SerialPort_Drain_ForwardToCallback&) = delete;
  SerialPort_Drain_ForwardToCallback& operator=(const SerialPort_Drain_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::DrainCallback callback_;
};

class SerialPort_GetControlSignals_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_GetControlSignals_ForwardToCallback(
      SerialPort::GetControlSignalsCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_GetControlSignals_ForwardToCallback(const SerialPort_GetControlSignals_ForwardToCallback&) = delete;
  SerialPort_GetControlSignals_ForwardToCallback& operator=(const SerialPort_GetControlSignals_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::GetControlSignalsCallback callback_;
};

class SerialPort_SetControlSignals_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_SetControlSignals_ForwardToCallback(
      SerialPort::SetControlSignalsCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_SetControlSignals_ForwardToCallback(const SerialPort_SetControlSignals_ForwardToCallback&) = delete;
  SerialPort_SetControlSignals_ForwardToCallback& operator=(const SerialPort_SetControlSignals_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::SetControlSignalsCallback callback_;
};

class SerialPort_ConfigurePort_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_ConfigurePort_ForwardToCallback(
      SerialPort::ConfigurePortCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_ConfigurePort_ForwardToCallback(const SerialPort_ConfigurePort_ForwardToCallback&) = delete;
  SerialPort_ConfigurePort_ForwardToCallback& operator=(const SerialPort_ConfigurePort_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::ConfigurePortCallback callback_;
};

class SerialPort_GetPortInfo_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_GetPortInfo_ForwardToCallback(
      SerialPort::GetPortInfoCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_GetPortInfo_ForwardToCallback(const SerialPort_GetPortInfo_ForwardToCallback&) = delete;
  SerialPort_GetPortInfo_ForwardToCallback& operator=(const SerialPort_GetPortInfo_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::GetPortInfoCallback callback_;
};

class SerialPort_Close_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  SerialPort_Close_ForwardToCallback(
      SerialPort::CloseCallback callback
      ) : callback_(std::move(callback)) {
  }

  SerialPort_Close_ForwardToCallback(const SerialPort_Close_ForwardToCallback&) = delete;
  SerialPort_Close_ForwardToCallback& operator=(const SerialPort_Close_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  SerialPort::CloseCallback callback_;
};

SerialPortProxy::SerialPortProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void SerialPortProxy::StartWriting(
    ::mojo::ScopedDataPipeConsumerHandle in_consumer) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::StartWriting", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("consumer"), in_consumer,
                        "<value of type ::mojo::ScopedDataPipeConsumerHandle>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kStartWriting), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_StartWriting_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::ScopedDataPipeConsumerHandle>(
      in_consumer, &params->consumer, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->consumer),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid consumer in SerialPort.StartWriting request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("StartWriting");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortProxy::StartReading(
    ::mojo::ScopedDataPipeProducerHandle in_producer) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::StartReading", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("producer"), in_producer,
                        "<value of type ::mojo::ScopedDataPipeProducerHandle>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kStartReading), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_StartReading_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::ScopedDataPipeProducerHandle>(
      in_producer, &params->producer, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->producer),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid producer in SerialPort.StartReading request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("StartReading");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortProxy::Flush(
    SerialPortFlushMode in_mode, FlushCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::Flush", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("mode"), in_mode,
                        "<value of type SerialPortFlushMode>");
   });
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kFlush), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Flush_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::SerialPortFlushMode>(
      in_mode, &params->mode);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Flush");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_Flush_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::Drain(
    DrainCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::SerialPort::Drain");
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kDrain), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Drain_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Drain");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_Drain_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::GetControlSignals(
    GetControlSignalsCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::SerialPort::GetControlSignals");
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kGetControlSignals), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_GetControlSignals_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("GetControlSignals");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_GetControlSignals_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::SetControlSignals(
    SerialHostControlSignalsPtr in_signals, SetControlSignalsCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::SetControlSignals", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("signals"), in_signals,
                        "<value of type SerialHostControlSignalsPtr>");
   });
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kSetControlSignals), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_SetControlSignals_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->signals)::BaseType> signals_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialHostControlSignalsDataView>(
      in_signals, signals_fragment);
  params->signals.Set(
      signals_fragment.is_null() ? nullptr : signals_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->signals.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null signals in SerialPort.SetControlSignals request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("SetControlSignals");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_SetControlSignals_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::ConfigurePort(
    SerialConnectionOptionsPtr in_options, ConfigurePortCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::ConfigurePort", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("options"), in_options,
                        "<value of type SerialConnectionOptionsPtr>");
   });
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kConfigurePort), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_ConfigurePort_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->options)::BaseType> options_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialConnectionOptionsDataView>(
      in_options, options_fragment);
  params->options.Set(
      options_fragment.is_null() ? nullptr : options_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->options.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null options in SerialPort.ConfigurePort request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("ConfigurePort");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_ConfigurePort_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::GetPortInfo(
    GetPortInfoCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send device::mojom::SerialPort::GetPortInfo");
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kGetPortInfo), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_GetPortInfo_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("GetPortInfo");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_GetPortInfo_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}

void SerialPortProxy::Close(
    bool in_flush, CloseCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPort::Close", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("flush"), in_flush,
                        "<value of type bool>");
   });
#endif

  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kClose), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Close_Params_Data> params(
          message);
  params.Allocate();
  params->flush = in_flush;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Close");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new SerialPort_Close_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
}
class SerialPort_Flush_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::FlushCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_Flush_ProxyToResponder> proxy(
        new SerialPort_Flush_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_Flush_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_Flush_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_Flush_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::FlushCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      );
};

bool SerialPort_Flush_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_Flush_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_Flush_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.2
  bool success = true;
  SerialPort_Flush_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run();
  return true;
}

void SerialPort_Flush_ProxyToResponder::Run(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send reply device::mojom::SerialPort::Flush");
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kFlush), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Flush_ResponseParams_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Flush");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_Drain_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::DrainCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_Drain_ProxyToResponder> proxy(
        new SerialPort_Drain_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_Drain_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_Drain_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_Drain_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::DrainCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      );
};

bool SerialPort_Drain_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_Drain_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_Drain_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.3
  bool success = true;
  SerialPort_Drain_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 3, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run();
  return true;
}

void SerialPort_Drain_ProxyToResponder::Run(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send reply device::mojom::SerialPort::Drain");
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kDrain), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Drain_ResponseParams_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Drain");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_GetControlSignals_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::GetControlSignalsCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_GetControlSignals_ProxyToResponder> proxy(
        new SerialPort_GetControlSignals_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_GetControlSignals_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_GetControlSignals_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_GetControlSignals_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::GetControlSignalsCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      SerialPortControlSignalsPtr in_signals);
};

bool SerialPort_GetControlSignals_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_GetControlSignals_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_GetControlSignals_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.4
  bool success = true;
  SerialPortControlSignalsPtr p_signals{};
  SerialPort_GetControlSignals_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadSignals(&p_signals))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 4, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_signals));
  return true;
}

void SerialPort_GetControlSignals_ProxyToResponder::Run(
    SerialPortControlSignalsPtr in_signals) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPort::GetControlSignals", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("signals"), in_signals,
                        "<value of type SerialPortControlSignalsPtr>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kGetControlSignals), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_GetControlSignals_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->signals)::BaseType> signals_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialPortControlSignalsDataView>(
      in_signals, signals_fragment);
  params->signals.Set(
      signals_fragment.is_null() ? nullptr : signals_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("GetControlSignals");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_SetControlSignals_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::SetControlSignalsCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_SetControlSignals_ProxyToResponder> proxy(
        new SerialPort_SetControlSignals_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_SetControlSignals_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_SetControlSignals_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_SetControlSignals_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::SetControlSignalsCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool SerialPort_SetControlSignals_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_SetControlSignals_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_SetControlSignals_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.5
  bool success = true;
  bool p_success{};
  SerialPort_SetControlSignals_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 5, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void SerialPort_SetControlSignals_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPort::SetControlSignals", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kSetControlSignals), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_SetControlSignals_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("SetControlSignals");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_ConfigurePort_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::ConfigurePortCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_ConfigurePort_ProxyToResponder> proxy(
        new SerialPort_ConfigurePort_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_ConfigurePort_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_ConfigurePort_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_ConfigurePort_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::ConfigurePortCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool SerialPort_ConfigurePort_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_ConfigurePort_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_ConfigurePort_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.6
  bool success = true;
  bool p_success{};
  SerialPort_ConfigurePort_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 6, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void SerialPort_ConfigurePort_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPort::ConfigurePort", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kConfigurePort), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_ConfigurePort_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("ConfigurePort");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_GetPortInfo_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::GetPortInfoCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_GetPortInfo_ProxyToResponder> proxy(
        new SerialPort_GetPortInfo_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_GetPortInfo_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_GetPortInfo_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_GetPortInfo_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::GetPortInfoCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      SerialConnectionInfoPtr in_info);
};

bool SerialPort_GetPortInfo_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_GetPortInfo_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_GetPortInfo_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.7
  bool success = true;
  SerialConnectionInfoPtr p_info{};
  SerialPort_GetPortInfo_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadInfo(&p_info))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 7, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_info));
  return true;
}

void SerialPort_GetPortInfo_ProxyToResponder::Run(
    SerialConnectionInfoPtr in_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply device::mojom::SerialPort::GetPortInfo", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("info"), in_info,
                        "<value of type SerialConnectionInfoPtr>");
   });
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kGetPortInfo), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_GetPortInfo_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->info)::BaseType> info_fragment(
          params.message());
  mojo::internal::Serialize<::device::mojom::SerialConnectionInfoDataView>(
      in_info, info_fragment);
  params->info.Set(
      info_fragment.is_null() ? nullptr : info_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->info.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null info in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("GetPortInfo");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class SerialPort_Close_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static SerialPort::CloseCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<SerialPort_Close_ProxyToResponder> proxy(
        new SerialPort_Close_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&SerialPort_Close_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~SerialPort_Close_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      // Instantiate a ScopedFizzleBlockShutdownTasks to allow this request to
      // fizzle if this happens after shutdown and the endpoint is bound to a
      // BLOCK_SHUTDOWN sequence.
      base::ThreadPoolInstance::ScopedFizzleBlockShutdownTasks fizzler;
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  SerialPort_Close_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "SerialPort::CloseCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      );
};

bool SerialPort_Close_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::SerialPort_Close_ResponseParams_Data* params =
      reinterpret_cast<
          internal::SerialPort_Close_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for SerialPort.8
  bool success = true;
  SerialPort_Close_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        SerialPort::Name_, 8, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run();
  return true;
}

void SerialPort_Close_ProxyToResponder::Run(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send reply device::mojom::SerialPort::Close");
#endif

  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((false) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPort::kClose), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPort_Close_ResponseParams_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPort::Name_);
  message.set_method_name("Close");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMojoMessage(*responder_, message);
  // SendMojoMessage() fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}

// static
bool SerialPortStubDispatch::Accept(
    SerialPort* impl,
    mojo::Message* message) {
  switch (static_cast<messages::SerialPort>(message->header()->name)) {
    case messages::SerialPort::kStartWriting: {
      DCHECK(message->is_serialized());
      internal::SerialPort_StartWriting_Params_Data* params =
          reinterpret_cast<internal::SerialPort_StartWriting_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPort.0
      bool success = true;
      ::mojo::ScopedDataPipeConsumerHandle p_consumer{};
      SerialPort_StartWriting_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_consumer = input_data_view.TakeConsumer();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->StartWriting(        
        std::move(p_consumer));
      return true;
    }
    case messages::SerialPort::kStartReading: {
      DCHECK(message->is_serialized());
      internal::SerialPort_StartReading_Params_Data* params =
          reinterpret_cast<internal::SerialPort_StartReading_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPort.1
      bool success = true;
      ::mojo::ScopedDataPipeProducerHandle p_producer{};
      SerialPort_StartReading_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_producer = input_data_view.TakeProducer();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->StartReading(        
        std::move(p_producer));
      return true;
    }
    case messages::SerialPort::kFlush: {
      break;
    }
    case messages::SerialPort::kDrain: {
      break;
    }
    case messages::SerialPort::kGetControlSignals: {
      break;
    }
    case messages::SerialPort::kSetControlSignals: {
      break;
    }
    case messages::SerialPort::kConfigurePort: {
      break;
    }
    case messages::SerialPort::kGetPortInfo: {
      break;
    }
    case messages::SerialPort::kClose: {
      break;
    }
  }
  return false;
}

// static
bool SerialPortStubDispatch::AcceptWithResponder(
    SerialPort* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (static_cast<messages::SerialPort>(message->header()->name)) {
    case messages::SerialPort::kStartWriting: {
      break;
    }
    case messages::SerialPort::kStartReading: {
      break;
    }
    case messages::SerialPort::kFlush: {
      internal::SerialPort_Flush_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_Flush_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.2
      bool success = true;
      SerialPortFlushMode p_mode{};
      SerialPort_Flush_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadMode(&p_mode))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 2, false);
        return false;
      }
      SerialPort::FlushCallback callback =
          SerialPort_Flush_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Flush(        
        std::move(p_mode), std::move(callback));
      return true;
    }
    case messages::SerialPort::kDrain: {
      internal::SerialPort_Drain_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_Drain_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.3
      bool success = true;
      SerialPort_Drain_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 3, false);
        return false;
      }
      SerialPort::DrainCallback callback =
          SerialPort_Drain_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Drain(std::move(callback));
      return true;
    }
    case messages::SerialPort::kGetControlSignals: {
      internal::SerialPort_GetControlSignals_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_GetControlSignals_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.4
      bool success = true;
      SerialPort_GetControlSignals_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 4, false);
        return false;
      }
      SerialPort::GetControlSignalsCallback callback =
          SerialPort_GetControlSignals_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetControlSignals(std::move(callback));
      return true;
    }
    case messages::SerialPort::kSetControlSignals: {
      internal::SerialPort_SetControlSignals_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_SetControlSignals_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.5
      bool success = true;
      SerialHostControlSignalsPtr p_signals{};
      SerialPort_SetControlSignals_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadSignals(&p_signals))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 5, false);
        return false;
      }
      SerialPort::SetControlSignalsCallback callback =
          SerialPort_SetControlSignals_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SetControlSignals(        
        std::move(p_signals), std::move(callback));
      return true;
    }
    case messages::SerialPort::kConfigurePort: {
      internal::SerialPort_ConfigurePort_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_ConfigurePort_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.6
      bool success = true;
      SerialConnectionOptionsPtr p_options{};
      SerialPort_ConfigurePort_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadOptions(&p_options))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 6, false);
        return false;
      }
      SerialPort::ConfigurePortCallback callback =
          SerialPort_ConfigurePort_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ConfigurePort(        
        std::move(p_options), std::move(callback));
      return true;
    }
    case messages::SerialPort::kGetPortInfo: {
      internal::SerialPort_GetPortInfo_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_GetPortInfo_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.7
      bool success = true;
      SerialPort_GetPortInfo_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 7, false);
        return false;
      }
      SerialPort::GetPortInfoCallback callback =
          SerialPort_GetPortInfo_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetPortInfo(std::move(callback));
      return true;
    }
    case messages::SerialPort::kClose: {
      internal::SerialPort_Close_Params_Data* params =
          reinterpret_cast<
              internal::SerialPort_Close_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for SerialPort.8
      bool success = true;
      bool p_flush{};
      SerialPort_Close_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_flush = input_data_view.flush();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPort::Name_, 8, false);
        return false;
      }
      SerialPort::CloseCallback callback =
          SerialPort_Close_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Close(        
        std::move(p_flush), std::move(callback));
      return true;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kSerialPortValidationInfo[] = {
    { &internal::SerialPort_StartWriting_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPort_StartReading_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPort_Flush_Params_Data::Validate,
     &internal::SerialPort_Flush_ResponseParams_Data::Validate},
    { &internal::SerialPort_Drain_Params_Data::Validate,
     &internal::SerialPort_Drain_ResponseParams_Data::Validate},
    { &internal::SerialPort_GetControlSignals_Params_Data::Validate,
     &internal::SerialPort_GetControlSignals_ResponseParams_Data::Validate},
    { &internal::SerialPort_SetControlSignals_Params_Data::Validate,
     &internal::SerialPort_SetControlSignals_ResponseParams_Data::Validate},
    { &internal::SerialPort_ConfigurePort_Params_Data::Validate,
     &internal::SerialPort_ConfigurePort_ResponseParams_Data::Validate},
    { &internal::SerialPort_GetPortInfo_Params_Data::Validate,
     &internal::SerialPort_GetPortInfo_ResponseParams_Data::Validate},
    { &internal::SerialPort_Close_Params_Data::Validate,
     &internal::SerialPort_Close_ResponseParams_Data::Validate},
};

bool SerialPortRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPort::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kSerialPortValidationInfo);
}

bool SerialPortResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPort::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kSerialPortValidationInfo);
}
const char SerialPortClient::Name_[] = "device.mojom.SerialPortClient";

SerialPortClient::IPCStableHashFunction SerialPortClient::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::SerialPortClient>(message.name())) {
    case messages::SerialPortClient::kOnReadError: {
      return &SerialPortClient::OnReadError_Sym::IPCStableHash;
    }
    case messages::SerialPortClient::kOnSendError: {
      return &SerialPortClient::OnSendError_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* SerialPortClient::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (static_cast<messages::SerialPortClient>(message.name())) {
      case messages::SerialPortClient::kOnReadError:
            return "Receive device::mojom::SerialPortClient::OnReadError";
      case messages::SerialPortClient::kOnSendError:
            return "Receive device::mojom::SerialPortClient::OnSendError";
    }
  } else {
    switch (static_cast<messages::SerialPortClient>(message.name())) {
      case messages::SerialPortClient::kOnReadError:
            return "Receive reply device::mojom::SerialPortClient::OnReadError";
      case messages::SerialPortClient::kOnSendError:
            return "Receive reply device::mojom::SerialPortClient::OnSendError";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
uint32_t SerialPortClient::OnReadError_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortClient::OnReadError");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t SerialPortClient::OnSendError_Sym::IPCStableHash() {
  // This method's address is used for indetifiying the mojo method name after
  // symbolization. So each IPCStableHash should have a unique address.
  // We cannot use NO_CODE_FOLDING() here - it relies on the uniqueness of
  // __LINE__ value, which is not unique accross different mojo modules.
  // The code below is very similar to NO_CODE_FOLDING, but it uses a unique
  // hash instead of __LINE__.
  constexpr uint32_t kHash = base::MD5Hash32Constexpr(
          "(Impl)device::mojom::SerialPortClient::OnSendError");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

SerialPortClientProxy::SerialPortClientProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void SerialPortClientProxy::OnReadError(
    SerialReceiveError in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortClient::OnReadError", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type SerialReceiveError>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortClient::kOnReadError), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortClient_OnReadError_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::SerialReceiveError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortClient::Name_);
  message.set_method_name("OnReadError");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

void SerialPortClientProxy::OnSendError(
    SerialSendError in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send device::mojom::SerialPortClient::OnSendError", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type SerialSendError>");
   });
#endif

  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  const bool is_urgent = false;

  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt) |
      ((is_urgent) ? mojo::Message::kFlagIsUrgent : 0);

  const size_t estimated_payload_size =
    0;
  mojo::Message message(
      base::to_underlying(messages::SerialPortClient::kOnSendError), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::device::mojom::internal::SerialPortClient_OnSendError_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::device::mojom::SerialSendError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(SerialPortClient::Name_);
  message.set_method_name("OnSendError");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMojoMessage(*receiver_, message);
}

// static
bool SerialPortClientStubDispatch::Accept(
    SerialPortClient* impl,
    mojo::Message* message) {
  switch (static_cast<messages::SerialPortClient>(message->header()->name)) {
    case messages::SerialPortClient::kOnReadError: {
      DCHECK(message->is_serialized());
      internal::SerialPortClient_OnReadError_Params_Data* params =
          reinterpret_cast<internal::SerialPortClient_OnReadError_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortClient.0
      bool success = true;
      SerialReceiveError p_error{};
      SerialPortClient_OnReadError_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadError(&p_error))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortClient::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnReadError(        
        std::move(p_error));
      return true;
    }
    case messages::SerialPortClient::kOnSendError: {
      DCHECK(message->is_serialized());
      internal::SerialPortClient_OnSendError_Params_Data* params =
          reinterpret_cast<internal::SerialPortClient_OnSendError_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for SerialPortClient.1
      bool success = true;
      SerialSendError p_error{};
      SerialPortClient_OnSendError_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadError(&p_error))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            SerialPortClient::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnSendError(        
        std::move(p_error));
      return true;
    }
  }
  return false;
}

// static
bool SerialPortClientStubDispatch::AcceptWithResponder(
    SerialPortClient* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (static_cast<messages::SerialPortClient>(message->header()->name)) {
    case messages::SerialPortClient::kOnReadError: {
      break;
    }
    case messages::SerialPortClient::kOnSendError: {
      break;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kSerialPortClientValidationInfo[] = {
    { &internal::SerialPortClient_OnReadError_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::SerialPortClient_OnSendError_Params_Data::Validate,
     nullptr /* no response */},
};

bool SerialPortClientRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPortClient::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kSerialPortClientValidationInfo);
}

const char SerialPortConnectionWatcher::Name_[] = "device.mojom.SerialPortConnectionWatcher";

SerialPortConnectionWatcher::IPCStableHashFunction SerialPortConnectionWatcher::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* SerialPortConnectionWatcher::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
# endif // !BUILDFLAG(IS_FUCHSIA)

SerialPortConnectionWatcherProxy::SerialPortConnectionWatcherProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

// static
bool SerialPortConnectionWatcherStubDispatch::Accept(
    SerialPortConnectionWatcher* impl,
    mojo::Message* message) {
  return false;
}

// static
bool SerialPortConnectionWatcherStubDispatch::AcceptWithResponder(
    SerialPortConnectionWatcher* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  return false;
}
namespace {
}  // namespace

bool SerialPortConnectionWatcherRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::device::mojom::blink::SerialPortConnectionWatcher::Name_;
  return mojo::internal::ValidateRequestGeneric(message, name, {});
}



}  // device::mojom::blink


namespace mojo {


// static
bool StructTraits<::device::mojom::blink::SerialPortInfo::DataView, ::device::mojom::blink::SerialPortInfoPtr>::Read(
    ::device::mojom::blink::SerialPortInfo::DataView input,
    ::device::mojom::blink::SerialPortInfoPtr* output) {
  bool success = true;
  ::device::mojom::blink::SerialPortInfoPtr result(::device::mojom::blink::SerialPortInfo::New());
  
      if (success && !input.ReadToken(&result->token))
        success = false;
      if (success && !input.ReadPath(&result->path))
        success = false;
      if (success && !input.ReadType(&result->type))
        success = false;
      if (success && !input.ReadDeviceInstanceId(&result->device_instance_id))
        success = false;
      if (success)
        result->vendor_id = input.vendor_id();
      if (success)
        result->has_vendor_id = input.has_vendor_id();
      if (success)
        result->product_id = input.product_id();
      if (success)
        result->has_product_id = input.has_product_id();
      if (success && !input.ReadBluetoothServiceClassId(&result->bluetooth_service_class_id))
        success = false;
      if (success && !input.ReadDisplayName(&result->display_name))
        success = false;
      if (success && !input.ReadSerialNumber(&result->serial_number))
        success = false;
      if (success)
        result->connected = input.connected();
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::blink::SerialConnectionOptions::DataView, ::device::mojom::blink::SerialConnectionOptionsPtr>::Read(
    ::device::mojom::blink::SerialConnectionOptions::DataView input,
    ::device::mojom::blink::SerialConnectionOptionsPtr* output) {
  bool success = true;
  ::device::mojom::blink::SerialConnectionOptionsPtr result(::device::mojom::blink::SerialConnectionOptions::New());
  
      if (success)
        result->bitrate = input.bitrate();
      if (success && !input.ReadDataBits(&result->data_bits))
        success = false;
      if (success && !input.ReadParityBit(&result->parity_bit))
        success = false;
      if (success && !input.ReadStopBits(&result->stop_bits))
        success = false;
      if (success)
        result->cts_flow_control = input.cts_flow_control();
      if (success)
        result->has_cts_flow_control = input.has_cts_flow_control();
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::blink::SerialConnectionInfo::DataView, ::device::mojom::blink::SerialConnectionInfoPtr>::Read(
    ::device::mojom::blink::SerialConnectionInfo::DataView input,
    ::device::mojom::blink::SerialConnectionInfoPtr* output) {
  bool success = true;
  ::device::mojom::blink::SerialConnectionInfoPtr result(::device::mojom::blink::SerialConnectionInfo::New());
  
      if (success)
        result->bitrate = input.bitrate();
      if (success && !input.ReadDataBits(&result->data_bits))
        success = false;
      if (success && !input.ReadParityBit(&result->parity_bit))
        success = false;
      if (success && !input.ReadStopBits(&result->stop_bits))
        success = false;
      if (success)
        result->cts_flow_control = input.cts_flow_control();
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::blink::SerialHostControlSignals::DataView, ::device::mojom::blink::SerialHostControlSignalsPtr>::Read(
    ::device::mojom::blink::SerialHostControlSignals::DataView input,
    ::device::mojom::blink::SerialHostControlSignalsPtr* output) {
  bool success = true;
  ::device::mojom::blink::SerialHostControlSignalsPtr result(::device::mojom::blink::SerialHostControlSignals::New());
  
      if (success)
        result->dtr = input.dtr();
      if (success)
        result->has_dtr = input.has_dtr();
      if (success)
        result->rts = input.rts();
      if (success)
        result->has_rts = input.has_rts();
      if (success)
        result->brk = input.brk();
      if (success)
        result->has_brk = input.has_brk();
  *output = std::move(result);
  return success;
}


// static
bool StructTraits<::device::mojom::blink::SerialPortControlSignals::DataView, ::device::mojom::blink::SerialPortControlSignalsPtr>::Read(
    ::device::mojom::blink::SerialPortControlSignals::DataView input,
    ::device::mojom::blink::SerialPortControlSignalsPtr* output) {
  bool success = true;
  ::device::mojom::blink::SerialPortControlSignalsPtr result(::device::mojom::blink::SerialPortControlSignals::New());
  
      if (success)
        result->dcd = input.dcd();
      if (success)
        result->cts = input.cts();
      if (success)
        result->ri = input.ri();
      if (success)
        result->dsr = input.dsr();
  *output = std::move(result);
  return success;
}

}  // namespace mojo


// Symbols declared in the -test-utils.h header are defined here instead of a
// separate .cc file to save compile time.


namespace device::mojom::blink {


void SerialPortManagerInterceptorForTesting::SetClient(::mojo::PendingRemote<SerialPortManagerClient> client) {
  GetForwardingInterface()->SetClient(
    std::move(client)
    );
}
void SerialPortManagerInterceptorForTesting::GetDevices(GetDevicesCallback callback) {
  GetForwardingInterface()->GetDevices(std::move(callback));
}
void SerialPortManagerInterceptorForTesting::OpenPort(const ::base::UnguessableToken& token, bool use_alternate_path, SerialConnectionOptionsPtr options, ::mojo::PendingRemote<SerialPortClient> client, ::mojo::PendingRemote<SerialPortConnectionWatcher> watcher, OpenPortCallback callback) {
  GetForwardingInterface()->OpenPort(
    std::move(token)
    , 
    std::move(use_alternate_path)
    , 
    std::move(options)
    , 
    std::move(client)
    , 
    std::move(watcher)
    , std::move(callback));
}
SerialPortManagerAsyncWaiter::SerialPortManagerAsyncWaiter(
    SerialPortManager* proxy) : proxy_(proxy) {}

SerialPortManagerAsyncWaiter::~SerialPortManagerAsyncWaiter() = default;

void SerialPortManagerAsyncWaiter::GetDevices(
    WTF::Vector<SerialPortInfoPtr>* out_devices) {
  base::RunLoop loop;
  proxy_->GetDevices(
      base::BindOnce(
          [](base::RunLoop* loop,
             WTF::Vector<SerialPortInfoPtr>* out_devices
,
             WTF::Vector<SerialPortInfoPtr> devices) {*out_devices = std::move(devices);
            loop->Quit();
          },
          &loop,
          out_devices));
  loop.Run();
}

WTF::Vector<SerialPortInfoPtr> SerialPortManagerAsyncWaiter::GetDevices(
    ) {
  WTF::Vector<SerialPortInfoPtr> async_wait_result;
  GetDevices(&async_wait_result);
  return async_wait_result;
}

void SerialPortManagerAsyncWaiter::OpenPort(
    const ::base::UnguessableToken& token, bool use_alternate_path, SerialConnectionOptionsPtr options, ::mojo::PendingRemote<SerialPortClient> client, ::mojo::PendingRemote<SerialPortConnectionWatcher> watcher, ::mojo::PendingRemote<SerialPort>* out_port) {
  base::RunLoop loop;
  proxy_->OpenPort(
      std::move(token),
      std::move(use_alternate_path),
      std::move(options),
      std::move(client),
      std::move(watcher),
      base::BindOnce(
          [](base::RunLoop* loop,
             ::mojo::PendingRemote<SerialPort>* out_port
,
             ::mojo::PendingRemote<SerialPort> port) {*out_port = std::move(port);
            loop->Quit();
          },
          &loop,
          out_port));
  loop.Run();
}

::mojo::PendingRemote<SerialPort> SerialPortManagerAsyncWaiter::OpenPort(
    const ::base::UnguessableToken& token, bool use_alternate_path, SerialConnectionOptionsPtr options, ::mojo::PendingRemote<SerialPortClient> client, ::mojo::PendingRemote<SerialPortConnectionWatcher> watcher) {
  ::mojo::PendingRemote<SerialPort> async_wait_result;
  OpenPort(std::move(token),std::move(use_alternate_path),std::move(options),std::move(client),std::move(watcher),&async_wait_result);
  return async_wait_result;
}




void SerialPortManagerClientInterceptorForTesting::OnPortAdded(SerialPortInfoPtr port_info) {
  GetForwardingInterface()->OnPortAdded(
    std::move(port_info)
    );
}
void SerialPortManagerClientInterceptorForTesting::OnPortRemoved(SerialPortInfoPtr port_info) {
  GetForwardingInterface()->OnPortRemoved(
    std::move(port_info)
    );
}
void SerialPortManagerClientInterceptorForTesting::OnPortConnectedStateChanged(SerialPortInfoPtr port_info) {
  GetForwardingInterface()->OnPortConnectedStateChanged(
    std::move(port_info)
    );
}
SerialPortManagerClientAsyncWaiter::SerialPortManagerClientAsyncWaiter(
    SerialPortManagerClient* proxy) : proxy_(proxy) {}

SerialPortManagerClientAsyncWaiter::~SerialPortManagerClientAsyncWaiter() = default;




void SerialPortInterceptorForTesting::StartWriting(::mojo::ScopedDataPipeConsumerHandle consumer) {
  GetForwardingInterface()->StartWriting(
    std::move(consumer)
    );
}
void SerialPortInterceptorForTesting::StartReading(::mojo::ScopedDataPipeProducerHandle producer) {
  GetForwardingInterface()->StartReading(
    std::move(producer)
    );
}
void SerialPortInterceptorForTesting::Flush(SerialPortFlushMode mode, FlushCallback callback) {
  GetForwardingInterface()->Flush(
    std::move(mode)
    , std::move(callback));
}
void SerialPortInterceptorForTesting::Drain(DrainCallback callback) {
  GetForwardingInterface()->Drain(std::move(callback));
}
void SerialPortInterceptorForTesting::GetControlSignals(GetControlSignalsCallback callback) {
  GetForwardingInterface()->GetControlSignals(std::move(callback));
}
void SerialPortInterceptorForTesting::SetControlSignals(SerialHostControlSignalsPtr signals, SetControlSignalsCallback callback) {
  GetForwardingInterface()->SetControlSignals(
    std::move(signals)
    , std::move(callback));
}
void SerialPortInterceptorForTesting::ConfigurePort(SerialConnectionOptionsPtr options, ConfigurePortCallback callback) {
  GetForwardingInterface()->ConfigurePort(
    std::move(options)
    , std::move(callback));
}
void SerialPortInterceptorForTesting::GetPortInfo(GetPortInfoCallback callback) {
  GetForwardingInterface()->GetPortInfo(std::move(callback));
}
void SerialPortInterceptorForTesting::Close(bool flush, CloseCallback callback) {
  GetForwardingInterface()->Close(
    std::move(flush)
    , std::move(callback));
}
SerialPortAsyncWaiter::SerialPortAsyncWaiter(
    SerialPort* proxy) : proxy_(proxy) {}

SerialPortAsyncWaiter::~SerialPortAsyncWaiter() = default;

void SerialPortAsyncWaiter::Flush(
    SerialPortFlushMode mode) {
  base::RunLoop loop;
  proxy_->Flush(
      std::move(mode),
      base::BindOnce(
          [](base::RunLoop* loop) {
            loop->Quit();
          },
          &loop));
  loop.Run();
}



void SerialPortAsyncWaiter::Drain(
    ) {
  base::RunLoop loop;
  proxy_->Drain(
      base::BindOnce(
          [](base::RunLoop* loop) {
            loop->Quit();
          },
          &loop));
  loop.Run();
}



void SerialPortAsyncWaiter::GetControlSignals(
    SerialPortControlSignalsPtr* out_signals) {
  base::RunLoop loop;
  proxy_->GetControlSignals(
      base::BindOnce(
          [](base::RunLoop* loop,
             SerialPortControlSignalsPtr* out_signals
,
             SerialPortControlSignalsPtr signals) {*out_signals = std::move(signals);
            loop->Quit();
          },
          &loop,
          out_signals));
  loop.Run();
}

SerialPortControlSignalsPtr SerialPortAsyncWaiter::GetControlSignals(
    ) {
  SerialPortControlSignalsPtr async_wait_result;
  GetControlSignals(&async_wait_result);
  return async_wait_result;
}

void SerialPortAsyncWaiter::SetControlSignals(
    SerialHostControlSignalsPtr signals, bool* out_success) {
  base::RunLoop loop;
  proxy_->SetControlSignals(
      std::move(signals),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}

bool SerialPortAsyncWaiter::SetControlSignals(
    SerialHostControlSignalsPtr signals) {
  bool async_wait_result;
  SetControlSignals(std::move(signals),&async_wait_result);
  return async_wait_result;
}

void SerialPortAsyncWaiter::ConfigurePort(
    SerialConnectionOptionsPtr options, bool* out_success) {
  base::RunLoop loop;
  proxy_->ConfigurePort(
      std::move(options),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}

bool SerialPortAsyncWaiter::ConfigurePort(
    SerialConnectionOptionsPtr options) {
  bool async_wait_result;
  ConfigurePort(std::move(options),&async_wait_result);
  return async_wait_result;
}

void SerialPortAsyncWaiter::GetPortInfo(
    SerialConnectionInfoPtr* out_info) {
  base::RunLoop loop;
  proxy_->GetPortInfo(
      base::BindOnce(
          [](base::RunLoop* loop,
             SerialConnectionInfoPtr* out_info
,
             SerialConnectionInfoPtr info) {*out_info = std::move(info);
            loop->Quit();
          },
          &loop,
          out_info));
  loop.Run();
}

SerialConnectionInfoPtr SerialPortAsyncWaiter::GetPortInfo(
    ) {
  SerialConnectionInfoPtr async_wait_result;
  GetPortInfo(&async_wait_result);
  return async_wait_result;
}

void SerialPortAsyncWaiter::Close(
    bool flush) {
  base::RunLoop loop;
  proxy_->Close(
      std::move(flush),
      base::BindOnce(
          [](base::RunLoop* loop) {
            loop->Quit();
          },
          &loop));
  loop.Run();
}






void SerialPortClientInterceptorForTesting::OnReadError(SerialReceiveError error) {
  GetForwardingInterface()->OnReadError(
    std::move(error)
    );
}
void SerialPortClientInterceptorForTesting::OnSendError(SerialSendError error) {
  GetForwardingInterface()->OnSendError(
    std::move(error)
    );
}
SerialPortClientAsyncWaiter::SerialPortClientAsyncWaiter(
    SerialPortClient* proxy) : proxy_(proxy) {}

SerialPortClientAsyncWaiter::~SerialPortClientAsyncWaiter() = default;




SerialPortConnectionWatcherAsyncWaiter::SerialPortConnectionWatcherAsyncWaiter(
    SerialPortConnectionWatcher* proxy) : proxy_(proxy) {}

SerialPortConnectionWatcherAsyncWaiter::~SerialPortConnectionWatcherAsyncWaiter() = default;






}  // device::mojom::blink


#if defined(__clang__)
#pragma clang diagnostic pop
#endif