// services/network/public/mojom/http_cache_backend_file_operations.mojom.cc is auto generated by mojom_bindings_generator.py, do not edit

// Copyright 2013 The Chromium Authors. All rights reserved.
// 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/network/public/mojom/http_cache_backend_file_operations.mojom.h"

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

#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.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/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.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/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"

#include "services/network/public/mojom/http_cache_backend_file_operations.mojom-params-data.h"
#include "services/network/public/mojom/http_cache_backend_file_operations.mojom-shared-message-ids.h"

#include "services/network/public/mojom/http_cache_backend_file_operations.mojom-import-headers.h"
#include "services/network/public/mojom/http_cache_backend_file_operations.mojom-test-utils.h"


#ifndef SERVICES_NETWORK_PUBLIC_MOJOM_HTTP_CACHE_BACKEND_FILE_OPERATIONS_MOJOM_JUMBO_H_
#define SERVICES_NETWORK_PUBLIC_MOJOM_HTTP_CACHE_BACKEND_FILE_OPERATIONS_MOJOM_JUMBO_H_
#endif



namespace network {
namespace mojom {
FileEnumerationEntry::FileEnumerationEntry()
    : path(),
      size(),
      last_accessed(),
      last_modified() {}

FileEnumerationEntry::FileEnumerationEntry(
    const ::base::FilePath& path_in,
    int64_t size_in,
    ::base::Time last_accessed_in,
    ::base::Time last_modified_in)
    : path(std::move(path_in)),
      size(std::move(size_in)),
      last_accessed(std::move(last_accessed_in)),
      last_modified(std::move(last_modified_in)) {}

FileEnumerationEntry::~FileEnumerationEntry() = default;

void FileEnumerationEntry::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  auto dict = std::move(traced_context).WriteDictionary();
  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(
      "size"), this->size,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type int64_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "last_accessed"), this->last_accessed,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type ::base::Time>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "last_modified"), this->last_modified,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type ::base::Time>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

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

uint32_t FileEnumerator::MessageToStableIPCHash_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kFileEnumerator_GetNext_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::FileEnumerator::GetNext");
      return value;
    }
  }
  return 0;
}


const char* FileEnumerator::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kFileEnumerator_GetNext_Name:
            return "Receive network::mojom::FileEnumerator::GetNext";
    }
  } else {
    switch (message.name()) {
      case internal::kFileEnumerator_GetNext_Name:
            return "Receive reply network::mojom::FileEnumerator::GetNext";
    }
  }
  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)
}
bool FileEnumerator::GetNext(uint32_t num_entries, std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_entries, bool* out_end, bool* out_error) {
  NOTREACHED();
  return false;
}
class FileEnumerator_GetNext_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  FileEnumerator_GetNext_HandleSyncResponse(
      bool* result, std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_entries, bool* out_end, bool* out_error)
      : result_(result), out_entries_(out_entries), out_end_(out_end), out_error_(out_error) {
    DCHECK(!*result_);
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  bool* result_;
  std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_entries_;
  bool* out_end_;
  bool* out_error_;};

class FileEnumerator_GetNext_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  FileEnumerator_GetNext_ForwardToCallback(
      FileEnumerator::GetNextCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  FileEnumerator::GetNextCallback callback_;
};

FileEnumeratorProxy::FileEnumeratorProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}
bool FileEnumeratorProxy::GetNext(
    uint32_t param_num_entries, std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_param_entries, bool* out_param_end, bool* out_param_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::FileEnumerator::GetNext (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("num_entries"), param_num_entries,
                        "<value of type uint32_t>");
   });
#else
  TRACE_EVENT0("mojom", "FileEnumerator::GetNext");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kFileEnumerator_GetNext_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::FileEnumerator_GetNext_Params_Data> params(
          message);
  params.Allocate();
  params->num_entries = param_num_entries;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(FileEnumerator::Name_);
  message.set_method_name("GetNext");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new FileEnumerator_GetNext_HandleSyncResponse(
          &result, out_param_entries, out_param_end, out_param_error));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "FileEnumerator::GetNext", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("entries"), out_param_entries,
                        "<value of type const std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("end"), out_param_end,
                        "<value of type bool>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), out_param_error,
                        "<value of type bool>");
   });
#endif
  return result;
}

void FileEnumeratorProxy::GetNext(
    uint32_t in_num_entries, GetNextCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::FileEnumerator::GetNext", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("num_entries"), in_num_entries,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kFileEnumerator_GetNext_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::FileEnumerator_GetNext_Params_Data> params(
          message);
  params.Allocate();
  params->num_entries = in_num_entries;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(FileEnumerator::Name_);
  message.set_method_name("GetNext");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new FileEnumerator_GetNext_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
class FileEnumerator_GetNext_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static FileEnumerator::GetNextCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<FileEnumerator_GetNext_ProxyToResponder> proxy(
        new FileEnumerator_GetNext_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&FileEnumerator_GetNext_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~FileEnumerator_GetNext_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  FileEnumerator_GetNext_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)
        << "FileEnumerator::GetNextCallback 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(
      const std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>& in_entries, bool in_end, bool in_error);
};

bool FileEnumerator_GetNext_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::FileEnumerator_GetNext_ResponseParams_Data* params =
      reinterpret_cast<
          internal::FileEnumerator_GetNext_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry> p_entries{};
  bool p_end{};
  bool p_error{};
  FileEnumerator_GetNext_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadEntries(&p_entries))
    success = false;
  if (success)
    p_end = input_data_view.end();
  if (success)
    p_error = input_data_view.error();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        FileEnumerator::Name_, 0, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_entries), 
std::move(p_end), 
std::move(p_error));
  return true;
}

void FileEnumerator_GetNext_ProxyToResponder::Run(
    const std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>& in_entries, bool in_end, bool in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::FileEnumerator::GetNext", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("entries"), in_entries,
                        "<value of type const std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("end"), in_end,
                        "<value of type bool>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kFileEnumerator_GetNext_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::FileEnumerator_GetNext_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->entries)::BaseType>
      entries_fragment(params.message());
  const mojo::internal::ContainerValidateParams entries_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<::network::mojom::FileEnumerationEntryDataView>>(
      in_entries, entries_fragment, &entries_validate_params);
  params->entries.Set(
      entries_fragment.is_null() ? nullptr : entries_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->entries.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null entries in ");
  params->end = in_end;
  params->error = in_error;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(FileEnumerator::Name_);
  message.set_method_name("GetNext");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 FileEnumerator_GetNext_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::FileEnumerator_GetNext_ResponseParams_Data* params =
      reinterpret_cast<internal::FileEnumerator_GetNext_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry> p_entries{};
  bool p_end{};
  bool p_error{};
  FileEnumerator_GetNext_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadEntries(&p_entries))
    success = false;
  if (success)
    p_end = input_data_view.end();
  if (success)
    p_error = input_data_view.error();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        FileEnumerator::Name_, 0, true);
    return false;
  }
  *out_entries_ = std::move(p_entries);
  *out_end_ = std::move(p_end);
  *out_error_ = std::move(p_error);
  *result_ = true;
  return true;
}

// static
bool FileEnumeratorStubDispatch::Accept(
    FileEnumerator* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kFileEnumerator_GetNext_Name: {
      break;
    }
  }
  return false;
}

// static
bool FileEnumeratorStubDispatch::AcceptWithResponder(
    FileEnumerator* 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 (message->header()->name) {
    case internal::kFileEnumerator_GetNext_Name: {

      internal::FileEnumerator_GetNext_Params_Data* params =
          reinterpret_cast<
              internal::FileEnumerator_GetNext_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      uint32_t p_num_entries{};
      FileEnumerator_GetNext_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_num_entries = input_data_view.num_entries();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            FileEnumerator::Name_, 0, false);
        return false;
      }
      FileEnumerator::GetNextCallback callback =
          FileEnumerator_GetNext_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetNext(
std::move(p_num_entries), std::move(callback));
      return true;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kFileEnumeratorValidationInfo[] = {
    {&internal::FileEnumerator_GetNext_Params_Data::Validate,
     &internal::FileEnumerator_GetNext_ResponseParams_Data::Validate},
};

bool FileEnumeratorRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::network::mojom::FileEnumerator::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kFileEnumeratorValidationInfo);
}

bool FileEnumeratorResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::network::mojom::FileEnumerator::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kFileEnumeratorValidationInfo);
}
const char HttpCacheBackendFileOperations::Name_[] = "network.mojom.HttpCacheBackendFileOperations";

uint32_t HttpCacheBackendFileOperations::MessageToStableIPCHash_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kHttpCacheBackendFileOperations_CreateDirectory_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::CreateDirectory");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_PathExists_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::PathExists");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_DirectoryExists_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::DirectoryExists");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_OpenFile_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::OpenFile");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_DeleteFile_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::DeleteFile");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_RenameFile_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::RenameFile");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_GetFileInfo_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::GetFileInfo");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::EnumerateFiles");
      return value;
    }
    case internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperations::CleanupDirectory");
      return value;
    }
  }
  return 0;
}


const char* HttpCacheBackendFileOperations::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kHttpCacheBackendFileOperations_CreateDirectory_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::CreateDirectory";
      case internal::kHttpCacheBackendFileOperations_PathExists_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::PathExists";
      case internal::kHttpCacheBackendFileOperations_DirectoryExists_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::DirectoryExists";
      case internal::kHttpCacheBackendFileOperations_OpenFile_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::OpenFile";
      case internal::kHttpCacheBackendFileOperations_DeleteFile_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::DeleteFile";
      case internal::kHttpCacheBackendFileOperations_RenameFile_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::RenameFile";
      case internal::kHttpCacheBackendFileOperations_GetFileInfo_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::GetFileInfo";
      case internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::EnumerateFiles";
      case internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperations::CleanupDirectory";
    }
  } else {
    switch (message.name()) {
      case internal::kHttpCacheBackendFileOperations_CreateDirectory_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::CreateDirectory";
      case internal::kHttpCacheBackendFileOperations_PathExists_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::PathExists";
      case internal::kHttpCacheBackendFileOperations_DirectoryExists_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::DirectoryExists";
      case internal::kHttpCacheBackendFileOperations_OpenFile_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::OpenFile";
      case internal::kHttpCacheBackendFileOperations_DeleteFile_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::DeleteFile";
      case internal::kHttpCacheBackendFileOperations_RenameFile_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::RenameFile";
      case internal::kHttpCacheBackendFileOperations_GetFileInfo_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::GetFileInfo";
      case internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::EnumerateFiles";
      case internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperations::CleanupDirectory";
    }
  }
  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)
}
bool HttpCacheBackendFileOperations::CreateDirectory(const ::base::FilePath& path, bool* out_result) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::PathExists(const ::base::FilePath& path, bool* out_result) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::DirectoryExists(const ::base::FilePath& path, bool* out_result) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::OpenFile(const ::base::FilePath& path, HttpCacheBackendOpenFileFlags flags, ::base::File* out_file, ::base::File::Error* out_error) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::DeleteFile(const ::base::FilePath& path, HttpCacheBackendDeleteFileMode mode, bool* out_result) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::RenameFile(const ::base::FilePath& from_path, const ::base::FilePath& to_path, ::base::File::Error* out_error) {
  NOTREACHED();
  return false;
}
bool HttpCacheBackendFileOperations::GetFileInfo(const ::base::FilePath& path, absl::optional<::base::File::Info>* out_info) {
  NOTREACHED();
  return false;
}
class HttpCacheBackendFileOperations_CreateDirectory_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_CreateDirectory_HandleSyncResponse(
      bool* result, bool* out_result)
      : result_(result), out_result_(out_result) {
    DCHECK(!*result_);
  }

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

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

class HttpCacheBackendFileOperations_CreateDirectory_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_CreateDirectory_ForwardToCallback(
      HttpCacheBackendFileOperations::CreateDirectoryCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::CreateDirectoryCallback callback_;
};
class HttpCacheBackendFileOperations_PathExists_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_PathExists_HandleSyncResponse(
      bool* result, bool* out_result)
      : result_(result), out_result_(out_result) {
    DCHECK(!*result_);
  }

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

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

class HttpCacheBackendFileOperations_PathExists_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_PathExists_ForwardToCallback(
      HttpCacheBackendFileOperations::PathExistsCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::PathExistsCallback callback_;
};
class HttpCacheBackendFileOperations_DirectoryExists_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_DirectoryExists_HandleSyncResponse(
      bool* result, bool* out_result)
      : result_(result), out_result_(out_result) {
    DCHECK(!*result_);
  }

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

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

class HttpCacheBackendFileOperations_DirectoryExists_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_DirectoryExists_ForwardToCallback(
      HttpCacheBackendFileOperations::DirectoryExistsCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::DirectoryExistsCallback callback_;
};
class HttpCacheBackendFileOperations_OpenFile_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_OpenFile_HandleSyncResponse(
      bool* result, ::base::File* out_file, ::base::File::Error* out_error)
      : result_(result), out_file_(out_file), out_error_(out_error) {
    DCHECK(!*result_);
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  bool* result_;
  ::base::File* out_file_;
  ::base::File::Error* out_error_;};

class HttpCacheBackendFileOperations_OpenFile_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_OpenFile_ForwardToCallback(
      HttpCacheBackendFileOperations::OpenFileCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::OpenFileCallback callback_;
};
class HttpCacheBackendFileOperations_DeleteFile_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_DeleteFile_HandleSyncResponse(
      bool* result, bool* out_result)
      : result_(result), out_result_(out_result) {
    DCHECK(!*result_);
  }

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

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

class HttpCacheBackendFileOperations_DeleteFile_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_DeleteFile_ForwardToCallback(
      HttpCacheBackendFileOperations::DeleteFileCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::DeleteFileCallback callback_;
};
class HttpCacheBackendFileOperations_RenameFile_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_RenameFile_HandleSyncResponse(
      bool* result, ::base::File::Error* out_error)
      : result_(result), out_error_(out_error) {
    DCHECK(!*result_);
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  bool* result_;
  ::base::File::Error* out_error_;};

class HttpCacheBackendFileOperations_RenameFile_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_RenameFile_ForwardToCallback(
      HttpCacheBackendFileOperations::RenameFileCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::RenameFileCallback callback_;
};
class HttpCacheBackendFileOperations_GetFileInfo_HandleSyncResponse
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_GetFileInfo_HandleSyncResponse(
      bool* result, absl::optional<::base::File::Info>* out_info)
      : result_(result), out_info_(out_info) {
    DCHECK(!*result_);
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  bool* result_;
  absl::optional<::base::File::Info>* out_info_;};

class HttpCacheBackendFileOperations_GetFileInfo_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_GetFileInfo_ForwardToCallback(
      HttpCacheBackendFileOperations::GetFileInfoCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::GetFileInfoCallback callback_;
};

class HttpCacheBackendFileOperations_CleanupDirectory_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  HttpCacheBackendFileOperations_CleanupDirectory_ForwardToCallback(
      HttpCacheBackendFileOperations::CleanupDirectoryCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  HttpCacheBackendFileOperations::CleanupDirectoryCallback callback_;
};

HttpCacheBackendFileOperationsProxy::HttpCacheBackendFileOperationsProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}
bool HttpCacheBackendFileOperationsProxy::CreateDirectory(
    const ::base::FilePath& param_path, bool* out_param_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::CreateDirectory (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::CreateDirectory");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_CreateDirectory_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_CreateDirectory_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.CreateDirectory request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("CreateDirectory");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_CreateDirectory_HandleSyncResponse(
          &result, out_param_result));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::CreateDirectory", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), out_param_result,
                        "<value of type bool>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::CreateDirectory(
    const ::base::FilePath& in_path, CreateDirectoryCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::CreateDirectory", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_CreateDirectory_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_CreateDirectory_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.CreateDirectory request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("CreateDirectory");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_CreateDirectory_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::PathExists(
    const ::base::FilePath& param_path, bool* out_param_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::PathExists (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::PathExists");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_PathExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_PathExists_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.PathExists request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("PathExists");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_PathExists_HandleSyncResponse(
          &result, out_param_result));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::PathExists", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), out_param_result,
                        "<value of type bool>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::PathExists(
    const ::base::FilePath& in_path, PathExistsCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::PathExists", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_PathExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_PathExists_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.PathExists request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("PathExists");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_PathExists_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::DirectoryExists(
    const ::base::FilePath& param_path, bool* out_param_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::DirectoryExists (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::DirectoryExists");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DirectoryExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DirectoryExists_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.DirectoryExists request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DirectoryExists");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_DirectoryExists_HandleSyncResponse(
          &result, out_param_result));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::DirectoryExists", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), out_param_result,
                        "<value of type bool>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::DirectoryExists(
    const ::base::FilePath& in_path, DirectoryExistsCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::DirectoryExists", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DirectoryExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DirectoryExists_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.DirectoryExists request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DirectoryExists");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_DirectoryExists_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::OpenFile(
    const ::base::FilePath& param_path, HttpCacheBackendOpenFileFlags param_flags, ::base::File* out_param_file, ::base::File::Error* out_param_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::OpenFile (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("flags"), param_flags,
                        "<value of type HttpCacheBackendOpenFileFlags>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::OpenFile");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_OpenFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_OpenFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.OpenFile request");
  mojo::internal::Serialize<::network::mojom::HttpCacheBackendOpenFileFlags>(
      param_flags, &params->flags);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("OpenFile");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_OpenFile_HandleSyncResponse(
          &result, out_param_file, out_param_error));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::OpenFile", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("file"), out_param_file,
                        "<value of type ::base::File>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), out_param_error,
                        "<value of type ::base::File::Error>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::OpenFile(
    const ::base::FilePath& in_path, HttpCacheBackendOpenFileFlags in_flags, OpenFileCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::OpenFile", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("flags"), in_flags,
                        "<value of type HttpCacheBackendOpenFileFlags>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_OpenFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_OpenFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.OpenFile request");
  mojo::internal::Serialize<::network::mojom::HttpCacheBackendOpenFileFlags>(
      in_flags, &params->flags);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("OpenFile");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_OpenFile_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::DeleteFile(
    const ::base::FilePath& param_path, HttpCacheBackendDeleteFileMode param_mode, bool* out_param_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::DeleteFile (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("mode"), param_mode,
                        "<value of type HttpCacheBackendDeleteFileMode>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::DeleteFile");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DeleteFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DeleteFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.DeleteFile request");
  mojo::internal::Serialize<::network::mojom::HttpCacheBackendDeleteFileMode>(
      param_mode, &params->mode);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DeleteFile");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_DeleteFile_HandleSyncResponse(
          &result, out_param_result));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::DeleteFile", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), out_param_result,
                        "<value of type bool>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::DeleteFile(
    const ::base::FilePath& in_path, HttpCacheBackendDeleteFileMode in_mode, DeleteFileCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::DeleteFile", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("mode"), in_mode,
                        "<value of type HttpCacheBackendDeleteFileMode>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DeleteFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DeleteFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.DeleteFile request");
  mojo::internal::Serialize<::network::mojom::HttpCacheBackendDeleteFileMode>(
      in_mode, &params->mode);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DeleteFile");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_DeleteFile_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::RenameFile(
    const ::base::FilePath& param_from_path, const ::base::FilePath& param_to_path, ::base::File::Error* out_param_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::RenameFile (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("from_path"), param_from_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("to_path"), param_to_path,
                        "<value of type const ::base::FilePath&>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::RenameFile");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_RenameFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_RenameFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->from_path)::BaseType> from_path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_from_path, from_path_fragment);
  params->from_path.Set(
      from_path_fragment.is_null() ? nullptr : from_path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->from_path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null from_path in HttpCacheBackendFileOperations.RenameFile request");
  mojo::internal::MessageFragment<
      typename decltype(params->to_path)::BaseType> to_path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_to_path, to_path_fragment);
  params->to_path.Set(
      to_path_fragment.is_null() ? nullptr : to_path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->to_path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null to_path in HttpCacheBackendFileOperations.RenameFile request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("RenameFile");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_RenameFile_HandleSyncResponse(
          &result, out_param_error));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::RenameFile", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), out_param_error,
                        "<value of type ::base::File::Error>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::RenameFile(
    const ::base::FilePath& in_from_path, const ::base::FilePath& in_to_path, RenameFileCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::RenameFile", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("from_path"), in_from_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("to_path"), in_to_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_RenameFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_RenameFile_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->from_path)::BaseType> from_path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_from_path, from_path_fragment);
  params->from_path.Set(
      from_path_fragment.is_null() ? nullptr : from_path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->from_path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null from_path in HttpCacheBackendFileOperations.RenameFile request");
  mojo::internal::MessageFragment<
      typename decltype(params->to_path)::BaseType> to_path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_to_path, to_path_fragment);
  params->to_path.Set(
      to_path_fragment.is_null() ? nullptr : to_path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->to_path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null to_path in HttpCacheBackendFileOperations.RenameFile request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("RenameFile");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_RenameFile_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
bool HttpCacheBackendFileOperationsProxy::GetFileInfo(
    const ::base::FilePath& param_path, absl::optional<::base::File::Info>* out_param_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_BEGIN1(
    "mojom", "Call network::mojom::HttpCacheBackendFileOperations::GetFileInfo (sync)", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), param_path,
                        "<value of type const ::base::FilePath&>");
   });
#else
  TRACE_EVENT0("mojom", "HttpCacheBackendFileOperations::GetFileInfo");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = true;
  const bool kAllowInterrupt =
      true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_GetFileInfo_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_GetFileInfo_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      param_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.GetFileInfo request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("GetFileInfo");
#endif

  bool result = false;
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_GetFileInfo_HandleSyncResponse(
          &result, out_param_info));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT_END1(
    "mojom", "HttpCacheBackendFileOperations::GetFileInfo", "sync_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("info"), out_param_info,
                        "<value of type const absl::optional<::base::File::Info>&>");
   });
#endif
  return result;
}

void HttpCacheBackendFileOperationsProxy::GetFileInfo(
    const ::base::FilePath& in_path, GetFileInfoCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::GetFileInfo", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_GetFileInfo_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_GetFileInfo_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.GetFileInfo request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("GetFileInfo");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_GetFileInfo_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void HttpCacheBackendFileOperationsProxy::EnumerateFiles(
    const ::base::FilePath& in_path, ::mojo::PendingReceiver<FileEnumerator> in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::EnumerateFiles", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::PendingReceiver<FileEnumerator>>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_EnumerateFiles_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.EnumerateFiles request");
  mojo::internal::Serialize<mojo::InterfaceRequestDataView<::network::mojom::FileEnumeratorInterfaceBase>>(
      in_receiver, &params->receiver, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->receiver),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid receiver in HttpCacheBackendFileOperations.EnumerateFiles request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("EnumerateFiles");
#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::SendMessage(*receiver_, message);
}

void HttpCacheBackendFileOperationsProxy::CleanupDirectory(
    const ::base::FilePath& in_path, CleanupDirectoryCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperations::CleanupDirectory", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("path"), in_path,
                        "<value of type const ::base::FilePath&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_CleanupDirectory_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->path)::BaseType> path_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FilePathDataView>(
      in_path, path_fragment);
  params->path.Set(
      path_fragment.is_null() ? nullptr : path_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->path.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null path in HttpCacheBackendFileOperations.CleanupDirectory request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("CleanupDirectory");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new HttpCacheBackendFileOperations_CleanupDirectory_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
class HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::CreateDirectoryCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_CreateDirectory_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_CreateDirectory_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)
        << "HttpCacheBackendFileOperations::CreateDirectoryCallback 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_result);
};

bool HttpCacheBackendFileOperations_CreateDirectory_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_CreateDirectory_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 0, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder::Run(
    bool in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::CreateDirectory", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_CreateDirectory_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->result = in_result;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("CreateDirectory");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_CreateDirectory_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_CreateDirectory_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 0, true);
    return false;
  }
  *out_result_ = std::move(p_result);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_PathExists_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::PathExistsCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_PathExists_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_PathExists_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_PathExists_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_PathExists_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_PathExists_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)
        << "HttpCacheBackendFileOperations::PathExistsCallback 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_result);
};

bool HttpCacheBackendFileOperations_PathExists_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_PathExists_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 1, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void HttpCacheBackendFileOperations_PathExists_ProxyToResponder::Run(
    bool in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::PathExists", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_PathExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->result = in_result;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("PathExists");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_PathExists_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_PathExists_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 1, true);
    return false;
  }
  *out_result_ = std::move(p_result);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::DirectoryExistsCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_DirectoryExists_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_DirectoryExists_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)
        << "HttpCacheBackendFileOperations::DirectoryExistsCallback 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_result);
};

bool HttpCacheBackendFileOperations_DirectoryExists_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_DirectoryExists_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder::Run(
    bool in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::DirectoryExists", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DirectoryExists_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->result = in_result;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DirectoryExists");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_DirectoryExists_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_DirectoryExists_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 2, true);
    return false;
  }
  *out_result_ = std::move(p_result);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_OpenFile_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::OpenFileCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_OpenFile_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_OpenFile_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_OpenFile_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_OpenFile_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_OpenFile_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)
        << "HttpCacheBackendFileOperations::OpenFileCallback 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(
      ::base::File in_file, ::base::File::Error in_error);
};

bool HttpCacheBackendFileOperations_OpenFile_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  ::base::File p_file{};
  ::base::File::Error p_error{};
  HttpCacheBackendFileOperations_OpenFile_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadFile(&p_file))
    success = false;
  if (success && !input_data_view.ReadError(&p_error))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 3, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_file), 
std::move(p_error));
  return true;
}

void HttpCacheBackendFileOperations_OpenFile_ProxyToResponder::Run(
    ::base::File in_file, ::base::File::Error in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::OpenFile", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("file"), in_file,
                        "<value of type ::base::File>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type ::base::File::Error>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_OpenFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->file)::BaseType> file_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FileDataView>(
      in_file, file_fragment);
  params->file.Set(
      file_fragment.is_null() ? nullptr : file_fragment.data());
  mojo::internal::Serialize<::mojo_base::mojom::FileError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("OpenFile");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_OpenFile_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  ::base::File p_file{};
  ::base::File::Error p_error{};
  HttpCacheBackendFileOperations_OpenFile_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadFile(&p_file))
    success = false;
  if (success && !input_data_view.ReadError(&p_error))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 3, true);
    return false;
  }
  *out_file_ = std::move(p_file);
  *out_error_ = std::move(p_error);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::DeleteFileCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_DeleteFile_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_DeleteFile_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)
        << "HttpCacheBackendFileOperations::DeleteFileCallback 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_result);
};

bool HttpCacheBackendFileOperations_DeleteFile_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_DeleteFile_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 4, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder::Run(
    bool in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::DeleteFile", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_DeleteFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->result = in_result;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("DeleteFile");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_DeleteFile_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_DeleteFile_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 4, true);
    return false;
  }
  *out_result_ = std::move(p_result);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_RenameFile_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::RenameFileCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_RenameFile_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_RenameFile_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_RenameFile_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_RenameFile_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_RenameFile_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)
        << "HttpCacheBackendFileOperations::RenameFileCallback 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(
      ::base::File::Error in_error);
};

bool HttpCacheBackendFileOperations_RenameFile_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  ::base::File::Error p_error{};
  HttpCacheBackendFileOperations_RenameFile_ResponseParamsDataView 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,
        HttpCacheBackendFileOperations::Name_, 5, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_error));
  return true;
}

void HttpCacheBackendFileOperations_RenameFile_ProxyToResponder::Run(
    ::base::File::Error in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::RenameFile", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type ::base::File::Error>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_RenameFile_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::mojo_base::mojom::FileError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("RenameFile");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_RenameFile_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  ::base::File::Error p_error{};
  HttpCacheBackendFileOperations_RenameFile_ResponseParamsDataView 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,
        HttpCacheBackendFileOperations::Name_, 5, true);
    return false;
  }
  *out_error_ = std::move(p_error);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::GetFileInfoCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_GetFileInfo_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_GetFileInfo_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)
        << "HttpCacheBackendFileOperations::GetFileInfoCallback 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(
      const absl::optional<::base::File::Info>& in_info);
};

bool HttpCacheBackendFileOperations_GetFileInfo_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  absl::optional<::base::File::Info> p_info{};
  HttpCacheBackendFileOperations_GetFileInfo_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,
        HttpCacheBackendFileOperations::Name_, 6, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_info));
  return true;
}

void HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder::Run(
    const absl::optional<::base::File::Info>& in_info) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::GetFileInfo", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("info"), in_info,
                        "<value of type const absl::optional<::base::File::Info>&>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_GetFileInfo_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->info)::BaseType> info_fragment(
          params.message());
  mojo::internal::Serialize<::mojo_base::mojom::FileInfoDataView>(
      in_info, info_fragment);
  params->info.Set(
      info_fragment.is_null() ? nullptr : info_fragment.data());

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("GetFileInfo");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperations_GetFileInfo_HandleSyncResponse::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data* params =
      reinterpret_cast<internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data*>(
          message->mutable_payload());
  
  bool success = true;
  absl::optional<::base::File::Info> p_info{};
  HttpCacheBackendFileOperations_GetFileInfo_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,
        HttpCacheBackendFileOperations::Name_, 6, true);
    return false;
  }
  *out_info_ = std::move(p_info);
  *result_ = true;
  return true;
}
class HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static HttpCacheBackendFileOperations::CleanupDirectoryCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder> proxy(
        new HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~HttpCacheBackendFileOperations_CleanupDirectory_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.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  HttpCacheBackendFileOperations_CleanupDirectory_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)
        << "HttpCacheBackendFileOperations::CleanupDirectoryCallback 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_result);
};

bool HttpCacheBackendFileOperations_CleanupDirectory_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::HttpCacheBackendFileOperations_CleanupDirectory_ResponseParams_Data* params =
      reinterpret_cast<
          internal::HttpCacheBackendFileOperations_CleanupDirectory_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_result{};
  HttpCacheBackendFileOperations_CleanupDirectory_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_result = input_data_view.result();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        HttpCacheBackendFileOperations::Name_, 8, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_result));
  return true;
}

void HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder::Run(
    bool in_result) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply network::mojom::HttpCacheBackendFileOperations::CleanupDirectory", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("result"), in_result,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperations_CleanupDirectory_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->result = in_result;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperations::Name_);
  message.set_method_name("CleanupDirectory");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage 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 HttpCacheBackendFileOperationsStubDispatch::Accept(
    HttpCacheBackendFileOperations* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kHttpCacheBackendFileOperations_CreateDirectory_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_PathExists_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_DirectoryExists_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_OpenFile_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_DeleteFile_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_RenameFile_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_GetFileInfo_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name: {

      DCHECK(message->is_serialized());
      internal::HttpCacheBackendFileOperations_EnumerateFiles_Params_Data* params =
          reinterpret_cast<internal::HttpCacheBackendFileOperations_EnumerateFiles_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      ::mojo::PendingReceiver<FileEnumerator> p_receiver{};
      HttpCacheBackendFileOperations_EnumerateFiles_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (success) {
        p_receiver =
            input_data_view.TakeReceiver<decltype(p_receiver)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 7, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->EnumerateFiles(
std::move(p_path), 
std::move(p_receiver));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name: {
      break;
    }
  }
  return false;
}

// static
bool HttpCacheBackendFileOperationsStubDispatch::AcceptWithResponder(
    HttpCacheBackendFileOperations* 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 (message->header()->name) {
    case internal::kHttpCacheBackendFileOperations_CreateDirectory_Name: {

      internal::HttpCacheBackendFileOperations_CreateDirectory_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_CreateDirectory_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendFileOperations_CreateDirectory_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 0, false);
        return false;
      }
      HttpCacheBackendFileOperations::CreateDirectoryCallback callback =
          HttpCacheBackendFileOperations_CreateDirectory_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->CreateDirectory(
std::move(p_path), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_PathExists_Name: {

      internal::HttpCacheBackendFileOperations_PathExists_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_PathExists_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendFileOperations_PathExists_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 1, false);
        return false;
      }
      HttpCacheBackendFileOperations::PathExistsCallback callback =
          HttpCacheBackendFileOperations_PathExists_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->PathExists(
std::move(p_path), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_DirectoryExists_Name: {

      internal::HttpCacheBackendFileOperations_DirectoryExists_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_DirectoryExists_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendFileOperations_DirectoryExists_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 2, false);
        return false;
      }
      HttpCacheBackendFileOperations::DirectoryExistsCallback callback =
          HttpCacheBackendFileOperations_DirectoryExists_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->DirectoryExists(
std::move(p_path), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_OpenFile_Name: {

      internal::HttpCacheBackendFileOperations_OpenFile_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_OpenFile_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendOpenFileFlags p_flags{};
      HttpCacheBackendFileOperations_OpenFile_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (success && !input_data_view.ReadFlags(&p_flags))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 3, false);
        return false;
      }
      HttpCacheBackendFileOperations::OpenFileCallback callback =
          HttpCacheBackendFileOperations_OpenFile_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OpenFile(
std::move(p_path), 
std::move(p_flags), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_DeleteFile_Name: {

      internal::HttpCacheBackendFileOperations_DeleteFile_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_DeleteFile_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendDeleteFileMode p_mode{};
      HttpCacheBackendFileOperations_DeleteFile_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (success && !input_data_view.ReadMode(&p_mode))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 4, false);
        return false;
      }
      HttpCacheBackendFileOperations::DeleteFileCallback callback =
          HttpCacheBackendFileOperations_DeleteFile_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->DeleteFile(
std::move(p_path), 
std::move(p_mode), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_RenameFile_Name: {

      internal::HttpCacheBackendFileOperations_RenameFile_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_RenameFile_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_from_path{};
      ::base::FilePath p_to_path{};
      HttpCacheBackendFileOperations_RenameFile_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadFromPath(&p_from_path))
        success = false;
      if (success && !input_data_view.ReadToPath(&p_to_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 5, false);
        return false;
      }
      HttpCacheBackendFileOperations::RenameFileCallback callback =
          HttpCacheBackendFileOperations_RenameFile_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->RenameFile(
std::move(p_from_path), 
std::move(p_to_path), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_GetFileInfo_Name: {

      internal::HttpCacheBackendFileOperations_GetFileInfo_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_GetFileInfo_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendFileOperations_GetFileInfo_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 6, false);
        return false;
      }
      HttpCacheBackendFileOperations::GetFileInfoCallback callback =
          HttpCacheBackendFileOperations_GetFileInfo_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetFileInfo(
std::move(p_path), std::move(callback));
      return true;
    }
    case internal::kHttpCacheBackendFileOperations_EnumerateFiles_Name: {
      break;
    }
    case internal::kHttpCacheBackendFileOperations_CleanupDirectory_Name: {

      internal::HttpCacheBackendFileOperations_CleanupDirectory_Params_Data* params =
          reinterpret_cast<
              internal::HttpCacheBackendFileOperations_CleanupDirectory_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      ::base::FilePath p_path{};
      HttpCacheBackendFileOperations_CleanupDirectory_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadPath(&p_path))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperations::Name_, 8, false);
        return false;
      }
      HttpCacheBackendFileOperations::CleanupDirectoryCallback callback =
          HttpCacheBackendFileOperations_CleanupDirectory_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->CleanupDirectory(
std::move(p_path), std::move(callback));
      return true;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kHttpCacheBackendFileOperationsValidationInfo[] = {
    {&internal::HttpCacheBackendFileOperations_CreateDirectory_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_CreateDirectory_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_PathExists_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_PathExists_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_DirectoryExists_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_DirectoryExists_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_OpenFile_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_OpenFile_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_DeleteFile_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_DeleteFile_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_RenameFile_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_RenameFile_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_GetFileInfo_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_GetFileInfo_ResponseParams_Data::Validate},
    {&internal::HttpCacheBackendFileOperations_EnumerateFiles_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::HttpCacheBackendFileOperations_CleanupDirectory_Params_Data::Validate,
     &internal::HttpCacheBackendFileOperations_CleanupDirectory_ResponseParams_Data::Validate},
};

bool HttpCacheBackendFileOperationsRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::network::mojom::HttpCacheBackendFileOperations::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kHttpCacheBackendFileOperationsValidationInfo);
}

bool HttpCacheBackendFileOperationsResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::network::mojom::HttpCacheBackendFileOperations::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kHttpCacheBackendFileOperationsValidationInfo);
}
const char HttpCacheBackendFileOperationsFactory::Name_[] = "network.mojom.HttpCacheBackendFileOperationsFactory";

uint32_t HttpCacheBackendFileOperationsFactory::MessageToStableIPCHash_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kHttpCacheBackendFileOperationsFactory_Create_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)network::mojom::HttpCacheBackendFileOperationsFactory::Create");
      return value;
    }
  }
  return 0;
}


const char* HttpCacheBackendFileOperationsFactory::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kHttpCacheBackendFileOperationsFactory_Create_Name:
            return "Receive network::mojom::HttpCacheBackendFileOperationsFactory::Create";
    }
  } else {
    switch (message.name()) {
      case internal::kHttpCacheBackendFileOperationsFactory_Create_Name:
            return "Receive reply network::mojom::HttpCacheBackendFileOperationsFactory::Create";
    }
  }
  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)
}

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

void HttpCacheBackendFileOperationsFactoryProxy::Create(
    ::mojo::PendingReceiver<HttpCacheBackendFileOperations> in_receiver) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send network::mojom::HttpCacheBackendFileOperationsFactory::Create", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("receiver"), in_receiver,
                        "<value of type ::mojo::PendingReceiver<HttpCacheBackendFileOperations>>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kHttpCacheBackendFileOperationsFactory_Create_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::network::mojom::internal::HttpCacheBackendFileOperationsFactory_Create_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfaceRequestDataView<::network::mojom::HttpCacheBackendFileOperationsInterfaceBase>>(
      in_receiver, &params->receiver, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->receiver),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid receiver in HttpCacheBackendFileOperationsFactory.Create request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(HttpCacheBackendFileOperationsFactory::Name_);
  message.set_method_name("Create");
#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::SendMessage(*receiver_, message);
}

// static
bool HttpCacheBackendFileOperationsFactoryStubDispatch::Accept(
    HttpCacheBackendFileOperationsFactory* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kHttpCacheBackendFileOperationsFactory_Create_Name: {

      DCHECK(message->is_serialized());
      internal::HttpCacheBackendFileOperationsFactory_Create_Params_Data* params =
          reinterpret_cast<internal::HttpCacheBackendFileOperationsFactory_Create_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::mojo::PendingReceiver<HttpCacheBackendFileOperations> p_receiver{};
      HttpCacheBackendFileOperationsFactory_Create_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_receiver =
            input_data_view.TakeReceiver<decltype(p_receiver)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            HttpCacheBackendFileOperationsFactory::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->Create(
std::move(p_receiver));
      return true;
    }
  }
  return false;
}

// static
bool HttpCacheBackendFileOperationsFactoryStubDispatch::AcceptWithResponder(
    HttpCacheBackendFileOperationsFactory* 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 (message->header()->name) {
    case internal::kHttpCacheBackendFileOperationsFactory_Create_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kHttpCacheBackendFileOperationsFactoryValidationInfo[] = {
    {&internal::HttpCacheBackendFileOperationsFactory_Create_Params_Data::Validate,
     nullptr /* no response */},
};

bool HttpCacheBackendFileOperationsFactoryRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::network::mojom::HttpCacheBackendFileOperationsFactory::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kHttpCacheBackendFileOperationsFactoryValidationInfo);
}



}  // namespace mojom
}  // namespace network


namespace mojo {


// static
bool StructTraits<::network::mojom::FileEnumerationEntry::DataView, ::network::mojom::FileEnumerationEntryPtr>::Read(
    ::network::mojom::FileEnumerationEntry::DataView input,
    ::network::mojom::FileEnumerationEntryPtr* output) {
  bool success = true;
  ::network::mojom::FileEnumerationEntryPtr result(::network::mojom::FileEnumerationEntry::New());
  
      if (success && !input.ReadPath(&result->path))
        success = false;
      if (success)
        result->size = input.size();
      if (success && !input.ReadLastAccessed(&result->last_accessed))
        success = false;
      if (success && !input.ReadLastModified(&result->last_modified))
        success = false;
  *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 network {
namespace mojom {


void FileEnumeratorInterceptorForTesting::GetNext(uint32_t num_entries, GetNextCallback callback) {
  GetForwardingInterface()->GetNext(std::move(num_entries), std::move(callback));
}
FileEnumeratorAsyncWaiter::FileEnumeratorAsyncWaiter(
    FileEnumerator* proxy) : proxy_(proxy) {}

FileEnumeratorAsyncWaiter::~FileEnumeratorAsyncWaiter() = default;

void FileEnumeratorAsyncWaiter::GetNext(
    uint32_t num_entries, std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_entries, bool* out_end, bool* out_error) {
  base::RunLoop loop;
  proxy_->GetNext(std::move(num_entries),
      base::BindOnce(
          [](base::RunLoop* loop,
             std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>* out_entries
,
             bool* out_end
,
             bool* out_error
,
             const std::vector<::disk_cache::BackendFileOperations::FileEnumerationEntry>& entries,
             bool end,
             bool error) {*out_entries = std::move(entries);*out_end = std::move(end);*out_error = std::move(error);
            loop->Quit();
          },
          &loop,
          out_entries,
          out_end,
          out_error));
  loop.Run();
}



void HttpCacheBackendFileOperationsInterceptorForTesting::CreateDirectory(const ::base::FilePath& path, CreateDirectoryCallback callback) {
  GetForwardingInterface()->CreateDirectory(std::move(path), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::PathExists(const ::base::FilePath& path, PathExistsCallback callback) {
  GetForwardingInterface()->PathExists(std::move(path), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::DirectoryExists(const ::base::FilePath& path, DirectoryExistsCallback callback) {
  GetForwardingInterface()->DirectoryExists(std::move(path), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::OpenFile(const ::base::FilePath& path, HttpCacheBackendOpenFileFlags flags, OpenFileCallback callback) {
  GetForwardingInterface()->OpenFile(std::move(path), std::move(flags), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::DeleteFile(const ::base::FilePath& path, HttpCacheBackendDeleteFileMode mode, DeleteFileCallback callback) {
  GetForwardingInterface()->DeleteFile(std::move(path), std::move(mode), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::RenameFile(const ::base::FilePath& from_path, const ::base::FilePath& to_path, RenameFileCallback callback) {
  GetForwardingInterface()->RenameFile(std::move(from_path), std::move(to_path), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::GetFileInfo(const ::base::FilePath& path, GetFileInfoCallback callback) {
  GetForwardingInterface()->GetFileInfo(std::move(path), std::move(callback));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::EnumerateFiles(const ::base::FilePath& path, ::mojo::PendingReceiver<FileEnumerator> receiver) {
  GetForwardingInterface()->EnumerateFiles(std::move(path), std::move(receiver));
}
void HttpCacheBackendFileOperationsInterceptorForTesting::CleanupDirectory(const ::base::FilePath& path, CleanupDirectoryCallback callback) {
  GetForwardingInterface()->CleanupDirectory(std::move(path), std::move(callback));
}
HttpCacheBackendFileOperationsAsyncWaiter::HttpCacheBackendFileOperationsAsyncWaiter(
    HttpCacheBackendFileOperations* proxy) : proxy_(proxy) {}

HttpCacheBackendFileOperationsAsyncWaiter::~HttpCacheBackendFileOperationsAsyncWaiter() = default;

void HttpCacheBackendFileOperationsAsyncWaiter::CreateDirectory(
    const ::base::FilePath& path, bool* out_result) {
  base::RunLoop loop;
  proxy_->CreateDirectory(std::move(path),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_result
,
             bool result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::PathExists(
    const ::base::FilePath& path, bool* out_result) {
  base::RunLoop loop;
  proxy_->PathExists(std::move(path),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_result
,
             bool result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::DirectoryExists(
    const ::base::FilePath& path, bool* out_result) {
  base::RunLoop loop;
  proxy_->DirectoryExists(std::move(path),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_result
,
             bool result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::OpenFile(
    const ::base::FilePath& path, HttpCacheBackendOpenFileFlags flags, ::base::File* out_file, ::base::File::Error* out_error) {
  base::RunLoop loop;
  proxy_->OpenFile(std::move(path),std::move(flags),
      base::BindOnce(
          [](base::RunLoop* loop,
             ::base::File* out_file
,
             ::base::File::Error* out_error
,
             ::base::File file,
             ::base::File::Error error) {*out_file = std::move(file);*out_error = std::move(error);
            loop->Quit();
          },
          &loop,
          out_file,
          out_error));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::DeleteFile(
    const ::base::FilePath& path, HttpCacheBackendDeleteFileMode mode, bool* out_result) {
  base::RunLoop loop;
  proxy_->DeleteFile(std::move(path),std::move(mode),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_result
,
             bool result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::RenameFile(
    const ::base::FilePath& from_path, const ::base::FilePath& to_path, ::base::File::Error* out_error) {
  base::RunLoop loop;
  proxy_->RenameFile(std::move(from_path),std::move(to_path),
      base::BindOnce(
          [](base::RunLoop* loop,
             ::base::File::Error* out_error
,
             ::base::File::Error error) {*out_error = std::move(error);
            loop->Quit();
          },
          &loop,
          out_error));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::GetFileInfo(
    const ::base::FilePath& path, absl::optional<::base::File::Info>* out_info) {
  base::RunLoop loop;
  proxy_->GetFileInfo(std::move(path),
      base::BindOnce(
          [](base::RunLoop* loop,
             absl::optional<::base::File::Info>* out_info
,
             const absl::optional<::base::File::Info>& info) {*out_info = std::move(info);
            loop->Quit();
          },
          &loop,
          out_info));
  loop.Run();
}
void HttpCacheBackendFileOperationsAsyncWaiter::CleanupDirectory(
    const ::base::FilePath& path, bool* out_result) {
  base::RunLoop loop;
  proxy_->CleanupDirectory(std::move(path),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_result
,
             bool result) {*out_result = std::move(result);
            loop->Quit();
          },
          &loop,
          out_result));
  loop.Run();
}



void HttpCacheBackendFileOperationsFactoryInterceptorForTesting::Create(::mojo::PendingReceiver<HttpCacheBackendFileOperations> receiver) {
  GetForwardingInterface()->Create(std::move(receiver));
}
HttpCacheBackendFileOperationsFactoryAsyncWaiter::HttpCacheBackendFileOperationsFactoryAsyncWaiter(
    HttpCacheBackendFileOperationsFactory* proxy) : proxy_(proxy) {}

HttpCacheBackendFileOperationsFactoryAsyncWaiter::~HttpCacheBackendFileOperationsFactoryAsyncWaiter() = default;






}  // namespace mojom
}  // namespace network


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