// mojo/public/cpp/bindings/tests/receiver_unittest.test-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 "mojo/public/cpp/bindings/tests/receiver_unittest.test-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 "mojo/public/cpp/bindings/tests/receiver_unittest.test-mojom-params-data.h"
#include "mojo/public/cpp/bindings/tests/receiver_unittest.test-mojom-shared-message-ids.h"

#include "mojo/public/cpp/bindings/tests/receiver_unittest.test-mojom-blink-import-headers.h"
#include "mojo/public/cpp/bindings/tests/receiver_unittest.test-mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"


namespace mojo::test::receiver_unittest::mojom::blink {
const char TestGenericBinder::Name_[] = "mojo.test.receiver_unittest.mojom.TestGenericBinder";

TestGenericBinder::IPCStableHashFunction TestGenericBinder::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::TestGenericBinder>(message.name())) {
    case messages::TestGenericBinder::kBindOptionalReceiver: {
      return &TestGenericBinder::BindOptionalReceiver_Sym::IPCStableHash;
    }
    case messages::TestGenericBinder::kBindReceiver: {
      return &TestGenericBinder::BindReceiver_Sym::IPCStableHash;
    }
    case messages::TestGenericBinder::kBindOptionalAssociatedReceiver: {
      return &TestGenericBinder::BindOptionalAssociatedReceiver_Sym::IPCStableHash;
    }
    case messages::TestGenericBinder::kBindAssociatedReceiver: {
      return &TestGenericBinder::BindAssociatedReceiver_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* TestGenericBinder::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::TestGenericBinder>(message.name())) {
      case messages::TestGenericBinder::kBindOptionalReceiver:
            return "Receive mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalReceiver";
      case messages::TestGenericBinder::kBindReceiver:
            return "Receive mojo::test::receiver_unittest::mojom::TestGenericBinder::BindReceiver";
      case messages::TestGenericBinder::kBindOptionalAssociatedReceiver:
            return "Receive mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalAssociatedReceiver";
      case messages::TestGenericBinder::kBindAssociatedReceiver:
            return "Receive mojo::test::receiver_unittest::mojom::TestGenericBinder::BindAssociatedReceiver";
    }
  } else {
    switch (static_cast<messages::TestGenericBinder>(message.name())) {
      case messages::TestGenericBinder::kBindOptionalReceiver:
            return "Receive reply mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalReceiver";
      case messages::TestGenericBinder::kBindReceiver:
            return "Receive reply mojo::test::receiver_unittest::mojom::TestGenericBinder::BindReceiver";
      case messages::TestGenericBinder::kBindOptionalAssociatedReceiver:
            return "Receive reply mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalAssociatedReceiver";
      case messages::TestGenericBinder::kBindAssociatedReceiver:
            return "Receive reply mojo::test::receiver_unittest::mojom::TestGenericBinder::BindAssociatedReceiver";
    }
  }
  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 TestGenericBinder::BindOptionalReceiver_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)mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalReceiver");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t TestGenericBinder::BindReceiver_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)mojo::test::receiver_unittest::mojom::TestGenericBinder::BindReceiver");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t TestGenericBinder::BindOptionalAssociatedReceiver_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)mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalAssociatedReceiver");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t TestGenericBinder::BindAssociatedReceiver_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)mojo::test::receiver_unittest::mojom::TestGenericBinder::BindAssociatedReceiver");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

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

void TestGenericBinderProxy::BindOptionalReceiver(
    ::mojo::GenericPendingReceiver in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalReceiver", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::GenericPendingReceiver>");
   });
#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::TestGenericBinder::kBindOptionalReceiver), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::TestGenericBinder_BindOptionalReceiver_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->receiver)::BaseType> receiver_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::GenericPendingReceiverDataView>(
      in_receiver, receiver_fragment);
  params->receiver.Set(
      receiver_fragment.is_null() ? nullptr : receiver_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(TestGenericBinder::Name_);
  message.set_method_name("BindOptionalReceiver");
#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 TestGenericBinderProxy::BindReceiver(
    ::mojo::GenericPendingReceiver in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send mojo::test::receiver_unittest::mojom::TestGenericBinder::BindReceiver", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::GenericPendingReceiver>");
   });
#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::TestGenericBinder::kBindReceiver), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::TestGenericBinder_BindReceiver_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->receiver)::BaseType> receiver_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::GenericPendingReceiverDataView>(
      in_receiver, receiver_fragment);
  params->receiver.Set(
      receiver_fragment.is_null() ? nullptr : receiver_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->receiver.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null receiver in TestGenericBinder.BindReceiver request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(TestGenericBinder::Name_);
  message.set_method_name("BindReceiver");
#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 TestGenericBinderProxy::BindOptionalAssociatedReceiver(
    ::mojo::GenericPendingAssociatedReceiver in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send mojo::test::receiver_unittest::mojom::TestGenericBinder::BindOptionalAssociatedReceiver", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::GenericPendingAssociatedReceiver>");
   });
#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::TestGenericBinder::kBindOptionalAssociatedReceiver), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::TestGenericBinder_BindOptionalAssociatedReceiver_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->receiver)::BaseType> receiver_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::GenericPendingAssociatedReceiverDataView>(
      in_receiver, receiver_fragment);
  params->receiver.Set(
      receiver_fragment.is_null() ? nullptr : receiver_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(TestGenericBinder::Name_);
  message.set_method_name("BindOptionalAssociatedReceiver");
#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 TestGenericBinderProxy::BindAssociatedReceiver(
    ::mojo::GenericPendingAssociatedReceiver in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send mojo::test::receiver_unittest::mojom::TestGenericBinder::BindAssociatedReceiver", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::GenericPendingAssociatedReceiver>");
   });
#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::TestGenericBinder::kBindAssociatedReceiver), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::TestGenericBinder_BindAssociatedReceiver_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->receiver)::BaseType> receiver_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::GenericPendingAssociatedReceiverDataView>(
      in_receiver, receiver_fragment);
  params->receiver.Set(
      receiver_fragment.is_null() ? nullptr : receiver_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->receiver.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null receiver in TestGenericBinder.BindAssociatedReceiver request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(TestGenericBinder::Name_);
  message.set_method_name("BindAssociatedReceiver");
#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 TestGenericBinderStubDispatch::Accept(
    TestGenericBinder* impl,
    mojo::Message* message) {
  switch (static_cast<messages::TestGenericBinder>(message->header()->name)) {
    case messages::TestGenericBinder::kBindOptionalReceiver: {
      DCHECK(message->is_serialized());
      internal::TestGenericBinder_BindOptionalReceiver_Params_Data* params =
          reinterpret_cast<internal::TestGenericBinder_BindOptionalReceiver_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for TestGenericBinder.0
      bool success = true;
      ::mojo::GenericPendingReceiver p_receiver{};
      TestGenericBinder_BindOptionalReceiver_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadReceiver(&p_receiver))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            TestGenericBinder::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->BindOptionalReceiver(        
        std::move(p_receiver));
      return true;
    }
    case messages::TestGenericBinder::kBindReceiver: {
      DCHECK(message->is_serialized());
      internal::TestGenericBinder_BindReceiver_Params_Data* params =
          reinterpret_cast<internal::TestGenericBinder_BindReceiver_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for TestGenericBinder.1
      bool success = true;
      ::mojo::GenericPendingReceiver p_receiver{};
      TestGenericBinder_BindReceiver_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadReceiver(&p_receiver))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            TestGenericBinder::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->BindReceiver(        
        std::move(p_receiver));
      return true;
    }
    case messages::TestGenericBinder::kBindOptionalAssociatedReceiver: {
      DCHECK(message->is_serialized());
      internal::TestGenericBinder_BindOptionalAssociatedReceiver_Params_Data* params =
          reinterpret_cast<internal::TestGenericBinder_BindOptionalAssociatedReceiver_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for TestGenericBinder.2
      bool success = true;
      ::mojo::GenericPendingAssociatedReceiver p_receiver{};
      TestGenericBinder_BindOptionalAssociatedReceiver_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadReceiver(&p_receiver))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            TestGenericBinder::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->BindOptionalAssociatedReceiver(        
        std::move(p_receiver));
      return true;
    }
    case messages::TestGenericBinder::kBindAssociatedReceiver: {
      DCHECK(message->is_serialized());
      internal::TestGenericBinder_BindAssociatedReceiver_Params_Data* params =
          reinterpret_cast<internal::TestGenericBinder_BindAssociatedReceiver_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for TestGenericBinder.3
      bool success = true;
      ::mojo::GenericPendingAssociatedReceiver p_receiver{};
      TestGenericBinder_BindAssociatedReceiver_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadReceiver(&p_receiver))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            TestGenericBinder::Name_, 3, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->BindAssociatedReceiver(        
        std::move(p_receiver));
      return true;
    }
  }
  return false;
}

// static
bool TestGenericBinderStubDispatch::AcceptWithResponder(
    TestGenericBinder* 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::TestGenericBinder>(message->header()->name)) {
    case messages::TestGenericBinder::kBindOptionalReceiver: {
      break;
    }
    case messages::TestGenericBinder::kBindReceiver: {
      break;
    }
    case messages::TestGenericBinder::kBindOptionalAssociatedReceiver: {
      break;
    }
    case messages::TestGenericBinder::kBindAssociatedReceiver: {
      break;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kTestGenericBinderValidationInfo[] = {
    { &internal::TestGenericBinder_BindOptionalReceiver_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::TestGenericBinder_BindReceiver_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::TestGenericBinder_BindOptionalAssociatedReceiver_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::TestGenericBinder_BindAssociatedReceiver_Params_Data::Validate,
     nullptr /* no response */},
};

bool TestGenericBinderRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::TestGenericBinder::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kTestGenericBinderValidationInfo);
}

const char TestInterface1::Name_[] = "mojo.test.receiver_unittest.mojom.TestInterface1";

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


const char* TestInterface1::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)

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

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

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

bool TestInterface1RequestValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::TestInterface1::Name_;
  return mojo::internal::ValidateRequestGeneric(message, name, {});
}

const char TestInterface2::Name_[] = "mojo.test.receiver_unittest.mojom.TestInterface2";

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


const char* TestInterface2::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)

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

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

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

bool TestInterface2RequestValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::TestInterface2::Name_;
  return mojo::internal::ValidateRequestGeneric(message, name, {});
}

const char RebindTestInterface::Name_[] = "mojo.test.receiver_unittest.mojom.RebindTestInterface";

RebindTestInterface::IPCStableHashFunction RebindTestInterface::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::RebindTestInterface>(message.name())) {
    case messages::RebindTestInterface::kBlockingUntilExternalSignalCall: {
      return &RebindTestInterface::BlockingUntilExternalSignalCall_Sym::IPCStableHash;
    }
    case messages::RebindTestInterface::kNormalCall: {
      return &RebindTestInterface::NormalCall_Sym::IPCStableHash;
    }
    case messages::RebindTestInterface::kSyncCall: {
      return &RebindTestInterface::SyncCall_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* RebindTestInterface::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::RebindTestInterface>(message.name())) {
      case messages::RebindTestInterface::kBlockingUntilExternalSignalCall:
            return "Receive mojo::test::receiver_unittest::mojom::RebindTestInterface::BlockingUntilExternalSignalCall";
      case messages::RebindTestInterface::kNormalCall:
            return "Receive mojo::test::receiver_unittest::mojom::RebindTestInterface::NormalCall";
      case messages::RebindTestInterface::kSyncCall:
            return "Receive mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall";
    }
  } else {
    switch (static_cast<messages::RebindTestInterface>(message.name())) {
      case messages::RebindTestInterface::kBlockingUntilExternalSignalCall:
            return "Receive reply mojo::test::receiver_unittest::mojom::RebindTestInterface::BlockingUntilExternalSignalCall";
      case messages::RebindTestInterface::kNormalCall:
            return "Receive reply mojo::test::receiver_unittest::mojom::RebindTestInterface::NormalCall";
      case messages::RebindTestInterface::kSyncCall:
            return "Receive reply mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall";
    }
  }
  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 RebindTestInterface::BlockingUntilExternalSignalCall_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)mojo::test::receiver_unittest::mojom::RebindTestInterface::BlockingUntilExternalSignalCall");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t RebindTestInterface::NormalCall_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)mojo::test::receiver_unittest::mojom::RebindTestInterface::NormalCall");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
uint32_t RebindTestInterface::SyncCall_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)mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)
bool RebindTestInterface::SyncCall() {
  NOTREACHED_IN_MIGRATION();
  return false;
}
class RebindTestInterface_SyncCall_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  RebindTestInterface_SyncCall_HandleSyncResponse(
      bool* result)
      : result_(result) {
    DCHECK(!*result_);
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  bool* result_;};

class RebindTestInterface_SyncCall_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  RebindTestInterface_SyncCall_ForwardToCallback(
      RebindTestInterface::SyncCallCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  RebindTestInterface::SyncCallCallback callback_;
};

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

void RebindTestInterfaceProxy::BlockingUntilExternalSignalCall(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send mojo::test::receiver_unittest::mojom::RebindTestInterface::BlockingUntilExternalSignalCall");
#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::RebindTestInterface::kBlockingUntilExternalSignalCall), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::RebindTestInterface_BlockingUntilExternalSignalCall_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(RebindTestInterface::Name_);
  message.set_method_name("BlockingUntilExternalSignalCall");
#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 RebindTestInterfaceProxy::NormalCall(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send mojo::test::receiver_unittest::mojom::RebindTestInterface::NormalCall");
#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::RebindTestInterface::kNormalCall), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::RebindTestInterface_NormalCall_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(RebindTestInterface::Name_);
  message.set_method_name("NormalCall");
#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);
}
bool RebindTestInterfaceProxy::SyncCall(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN0("mojom", "Call mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall (sync)");
#else
  TRACE_EVENT0("mojom", "RebindTestInterface::SyncCall");
#endif
  
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  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::RebindTestInterface::kSyncCall), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::RebindTestInterface_SyncCall_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(RebindTestInterface::Name_);
  message.set_method_name("SyncCall");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new RebindTestInterface_SyncCall_HandleSyncResponse(
          &result));
  ::mojo::internal::SendMojoMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END0("mojom", "RebindTestInterface::SyncCall");
#endif
  return result;
}

void RebindTestInterfaceProxy::SyncCall(
    SyncCallCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall");
#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::RebindTestInterface::kSyncCall), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::RebindTestInterface_SyncCall_Params_Data> params(
          message);
  params.Allocate();

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

  ~RebindTestInterface_SyncCall_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:
  RebindTestInterface_SyncCall_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)
        << "RebindTestInterface::SyncCallCallback 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 RebindTestInterface_SyncCall_ForwardToCallback::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::RebindTestInterface_SyncCall_ResponseParams_Data* params =
      reinterpret_cast<
          internal::RebindTestInterface_SyncCall_ResponseParams_Data*>(
              message->mutable_payload());
  
  
  // Validation for RebindTestInterface.2
  bool success = true;
  RebindTestInterface_SyncCall_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        RebindTestInterface::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run();
  return true;
}

void RebindTestInterface_SyncCall_ProxyToResponder::Run(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send reply mojo::test::receiver_unittest::mojom::RebindTestInterface::SyncCall");
#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::RebindTestInterface::kSyncCall), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::RebindTestInterface_SyncCall_ResponseParams_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(RebindTestInterface::Name_);
  message.set_method_name("SyncCall");
#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;
}
bool RebindTestInterface_SyncCall_HandleSyncResponse::Accept(
    mojo::Message* message) {
  DCHECK(message->is_serialized());
  internal::RebindTestInterface_SyncCall_ResponseParams_Data* params =
      reinterpret_cast<internal::RebindTestInterface_SyncCall_ResponseParams_Data*>(
          message->mutable_payload());
  
  
  // Validation for RebindTestInterface.2
  bool success = true;
  RebindTestInterface_SyncCall_ResponseParamsDataView input_data_view(params, message);
  
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        RebindTestInterface::Name_, 2, true);
    return false;
  }
  *result_ = true;
  return true;
}

// static
bool RebindTestInterfaceStubDispatch::Accept(
    RebindTestInterface* impl,
    mojo::Message* message) {
  switch (static_cast<messages::RebindTestInterface>(message->header()->name)) {
    case messages::RebindTestInterface::kBlockingUntilExternalSignalCall: {
      DCHECK(message->is_serialized());
      internal::RebindTestInterface_BlockingUntilExternalSignalCall_Params_Data* params =
          reinterpret_cast<internal::RebindTestInterface_BlockingUntilExternalSignalCall_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for RebindTestInterface.0
      bool success = true;
      RebindTestInterface_BlockingUntilExternalSignalCall_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            RebindTestInterface::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->BlockingUntilExternalSignalCall(        );
      return true;
    }
    case messages::RebindTestInterface::kNormalCall: {
      DCHECK(message->is_serialized());
      internal::RebindTestInterface_NormalCall_Params_Data* params =
          reinterpret_cast<internal::RebindTestInterface_NormalCall_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for RebindTestInterface.1
      bool success = true;
      RebindTestInterface_NormalCall_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            RebindTestInterface::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->NormalCall(        );
      return true;
    }
    case messages::RebindTestInterface::kSyncCall: {
      break;
    }
  }
  return false;
}

// static
bool RebindTestInterfaceStubDispatch::AcceptWithResponder(
    RebindTestInterface* 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::RebindTestInterface>(message->header()->name)) {
    case messages::RebindTestInterface::kBlockingUntilExternalSignalCall: {
      break;
    }
    case messages::RebindTestInterface::kNormalCall: {
      break;
    }
    case messages::RebindTestInterface::kSyncCall: {
      internal::RebindTestInterface_SyncCall_Params_Data* params =
          reinterpret_cast<
              internal::RebindTestInterface_SyncCall_Params_Data*>(
                  message->mutable_payload());
      
      
      // Validation for RebindTestInterface.2
      bool success = true;
      RebindTestInterface_SyncCall_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            RebindTestInterface::Name_, 2, false);
        return false;
      }
      RebindTestInterface::SyncCallCallback callback =
          RebindTestInterface_SyncCall_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->SyncCall(std::move(callback));
      return true;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kRebindTestInterfaceValidationInfo[] = {
    { &internal::RebindTestInterface_BlockingUntilExternalSignalCall_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::RebindTestInterface_NormalCall_Params_Data::Validate,
     nullptr /* no response */},
    { &internal::RebindTestInterface_SyncCall_Params_Data::Validate,
     &internal::RebindTestInterface_SyncCall_ResponseParams_Data::Validate},
};

bool RebindTestInterfaceRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::RebindTestInterface::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kRebindTestInterfaceValidationInfo);
}

bool RebindTestInterfaceResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::RebindTestInterface::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kRebindTestInterfaceValidationInfo);
}
const char InterfaceDropper::Name_[] = "mojo.test.receiver_unittest.mojom.InterfaceDropper";

InterfaceDropper::IPCStableHashFunction InterfaceDropper::MessageToMethodInfo_(mojo::Message& message) {
#if !BUILDFLAG(IS_FUCHSIA)
  switch (static_cast<messages::InterfaceDropper>(message.name())) {
    case messages::InterfaceDropper::kDrop: {
      return &InterfaceDropper::Drop_Sym::IPCStableHash;
    }
  }
#endif  // !BUILDFLAG(IS_FUCHSIA)
  return nullptr;
}


const char* InterfaceDropper::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::InterfaceDropper>(message.name())) {
      case messages::InterfaceDropper::kDrop:
            return "Receive mojo::test::receiver_unittest::mojom::InterfaceDropper::Drop";
    }
  } else {
    switch (static_cast<messages::InterfaceDropper>(message.name())) {
      case messages::InterfaceDropper::kDrop:
            return "Receive reply mojo::test::receiver_unittest::mojom::InterfaceDropper::Drop";
    }
  }
  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 InterfaceDropper::Drop_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)mojo::test::receiver_unittest::mojom::InterfaceDropper::Drop");
  const uint32_t hash = kHash;
  base::debug::Alias(&hash);
  return hash;
}
# endif // !BUILDFLAG(IS_FUCHSIA)

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

void InterfaceDropperProxy::Drop(
    ::mojo::PendingRemote<TestInterface1> in_remote) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send mojo::test::receiver_unittest::mojom::InterfaceDropper::Drop", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("remote"), in_remote,
                        "<value of type ::mojo::PendingRemote<TestInterface1>>");
   });
#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::InterfaceDropper::kDrop), kFlags, estimated_payload_size);
  mojo::internal::MessageFragment<
      ::mojo::test::receiver_unittest::mojom::internal::InterfaceDropper_Drop_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::mojo::test::receiver_unittest::mojom::TestInterface1InterfaceBase>>(
      in_remote, &params->remote, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->remote),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid remote in InterfaceDropper.Drop request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(InterfaceDropper::Name_);
  message.set_method_name("Drop");
#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 InterfaceDropperStubDispatch::Accept(
    InterfaceDropper* impl,
    mojo::Message* message) {
  switch (static_cast<messages::InterfaceDropper>(message->header()->name)) {
    case messages::InterfaceDropper::kDrop: {
      DCHECK(message->is_serialized());
      internal::InterfaceDropper_Drop_Params_Data* params =
          reinterpret_cast<internal::InterfaceDropper_Drop_Params_Data*>(
              message->mutable_payload());
      
      
      // Validation for InterfaceDropper.0
      bool success = true;
      ::mojo::PendingRemote<TestInterface1> p_remote{};
      InterfaceDropper_Drop_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_remote =
            input_data_view.TakeRemote<decltype(p_remote)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            InterfaceDropper::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Drop(        
        std::move(p_remote));
      return true;
    }
  }
  return false;
}

// static
bool InterfaceDropperStubDispatch::AcceptWithResponder(
    InterfaceDropper* 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::InterfaceDropper>(message->header()->name)) {
    case messages::InterfaceDropper::kDrop: {
      break;
    }
  }
  return false;
}
namespace {
}  // namespace
static const mojo::internal::GenericValidationInfo kInterfaceDropperValidationInfo[] = {
    { &internal::InterfaceDropper_Drop_Params_Data::Validate,
     nullptr /* no response */},
};

bool InterfaceDropperRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::mojo::test::receiver_unittest::mojom::blink::InterfaceDropper::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kInterfaceDropperValidationInfo);
}



}  // mojo::test::receiver_unittest::mojom::blink


namespace mojo {

}  // namespace mojo


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


namespace mojo::test::receiver_unittest::mojom::blink {


void TestGenericBinderInterceptorForTesting::BindOptionalReceiver(::mojo::GenericPendingReceiver receiver) {
  GetForwardingInterface()->BindOptionalReceiver(
    std::move(receiver)
    );
}
void TestGenericBinderInterceptorForTesting::BindReceiver(::mojo::GenericPendingReceiver receiver) {
  GetForwardingInterface()->BindReceiver(
    std::move(receiver)
    );
}
void TestGenericBinderInterceptorForTesting::BindOptionalAssociatedReceiver(::mojo::GenericPendingAssociatedReceiver receiver) {
  GetForwardingInterface()->BindOptionalAssociatedReceiver(
    std::move(receiver)
    );
}
void TestGenericBinderInterceptorForTesting::BindAssociatedReceiver(::mojo::GenericPendingAssociatedReceiver receiver) {
  GetForwardingInterface()->BindAssociatedReceiver(
    std::move(receiver)
    );
}
TestGenericBinderAsyncWaiter::TestGenericBinderAsyncWaiter(
    TestGenericBinder* proxy) : proxy_(proxy) {}

TestGenericBinderAsyncWaiter::~TestGenericBinderAsyncWaiter() = default;




TestInterface1AsyncWaiter::TestInterface1AsyncWaiter(
    TestInterface1* proxy) : proxy_(proxy) {}

TestInterface1AsyncWaiter::~TestInterface1AsyncWaiter() = default;




TestInterface2AsyncWaiter::TestInterface2AsyncWaiter(
    TestInterface2* proxy) : proxy_(proxy) {}

TestInterface2AsyncWaiter::~TestInterface2AsyncWaiter() = default;




void RebindTestInterfaceInterceptorForTesting::BlockingUntilExternalSignalCall() {
  GetForwardingInterface()->BlockingUntilExternalSignalCall();
}
void RebindTestInterfaceInterceptorForTesting::NormalCall() {
  GetForwardingInterface()->NormalCall();
}
void RebindTestInterfaceInterceptorForTesting::SyncCall(SyncCallCallback callback) {
  GetForwardingInterface()->SyncCall(std::move(callback));
}
RebindTestInterfaceAsyncWaiter::RebindTestInterfaceAsyncWaiter(
    RebindTestInterface* proxy) : proxy_(proxy) {}

RebindTestInterfaceAsyncWaiter::~RebindTestInterfaceAsyncWaiter() = default;

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






void InterfaceDropperInterceptorForTesting::Drop(::mojo::PendingRemote<TestInterface1> remote) {
  GetForwardingInterface()->Drop(
    std::move(remote)
    );
}
InterfaceDropperAsyncWaiter::InterfaceDropperAsyncWaiter(
    InterfaceDropper* proxy) : proxy_(proxy) {}

InterfaceDropperAsyncWaiter::~InterfaceDropperAsyncWaiter() = default;






}  // mojo::test::receiver_unittest::mojom::blink


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