// third_party/blink/public/mojom/payments/payment_handler_host.mojom.h 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.

#ifndef THIRD_PARTY_BLINK_PUBLIC_MOJOM_PAYMENTS_PAYMENT_HANDLER_HOST_MOJOM_H_
#define THIRD_PARTY_BLINK_PUBLIC_MOJOM_PAYMENTS_PAYMENT_HANDLER_HOST_MOJOM_H_

#include <stdint.h>

#include <limits>
#include <type_traits>
#include <utility>

#include "third_party/abseil-cpp/absl/types/optional.h"
#include "mojo/public/cpp/bindings/clone_traits.h"
#include "mojo/public/cpp/bindings/equals_traits.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"

#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"

#include "third_party/blink/public/mojom/payments/payment_handler_host.mojom-shared.h"
#include "third_party/blink/public/mojom/payments/payment_handler_host.mojom-forward.h"
#include "components/payments/mojom/payment_request_data.mojom.h"
#include "third_party/blink/public/mojom/payments/payment_request.mojom.h"
#include <string>
#include <vector>

#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"


#include "third_party/blink/public/common/common_export.h"

#ifdef KYTHE_IS_RUNNING
#pragma kythe_inline_metadata "Metadata comment"
#endif


namespace payments {
namespace mojom {

class PaymentHandlerHostProxy;

template <typename ImplRefTraits>
class PaymentHandlerHostStub;

class PaymentHandlerHostRequestValidator;
class PaymentHandlerHostResponseValidator;


// @generated_from: payments.mojom.PaymentHandlerHost
class BLINK_COMMON_EXPORT PaymentHandlerHost
    : public PaymentHandlerHostInterfaceBase {
 public:
  static const char Name_[];
  static std::pair<uint32_t, const void*> MessageToMethodInfo_(mojo::Message& message);
  static const char* MessageToMethodName_(mojo::Message& message);
  static constexpr uint32_t Version_ = 0;
  static constexpr bool PassesAssociatedKinds_ = false;
  static constexpr bool HasSyncMethods_ = false;
  static constexpr bool HasUninterruptableMethods_ = false;

  using Base_ = PaymentHandlerHostInterfaceBase;
  using Proxy_ = PaymentHandlerHostProxy;

  template <typename ImplRefTraits>
  using Stub_ = PaymentHandlerHostStub<ImplRefTraits>;

  using RequestValidator_ = PaymentHandlerHostRequestValidator;
  using ResponseValidator_ = PaymentHandlerHostResponseValidator;
  enum MethodMinVersions : uint32_t {
    kChangePaymentMethodMinVersion = 0,
    kChangeShippingOptionMinVersion = 0,
    kChangeShippingAddressMinVersion = 0,
  };

// crbug.com/1340245 - this causes binary size bloat on Fuchsia, and we're OK
// with not having this data in traces there.
#if !BUILDFLAG(IS_FUCHSIA)
  struct ChangePaymentMethod_Sym {
    NOINLINE static void IPCSymbol();
  };
  struct ChangeShippingOption_Sym {
    NOINLINE static void IPCSymbol();
  };
  struct ChangeShippingAddress_Sym {
    NOINLINE static void IPCSymbol();
  };
#endif // !BUILDFLAG(IS_FUCHSIA)
  virtual ~PaymentHandlerHost() = default;


  using ChangePaymentMethodCallback = base::OnceCallback<void(PaymentRequestDetailsUpdatePtr)>;
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangePaymentMethod
  virtual void ChangePaymentMethod(PaymentHandlerMethodDataPtr method_data, ChangePaymentMethodCallback callback) = 0;


  using ChangeShippingOptionCallback = base::OnceCallback<void(PaymentRequestDetailsUpdatePtr)>;
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangeShippingOption
  virtual void ChangeShippingOption(const std::string& shipping_option_id, ChangeShippingOptionCallback callback) = 0;


  using ChangeShippingAddressCallback = base::OnceCallback<void(PaymentRequestDetailsUpdatePtr)>;
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangeShippingAddress
  virtual void ChangeShippingAddress(::payments::mojom::PaymentAddressPtr shipping_address, ChangeShippingAddressCallback callback) = 0;
};



// @generated_from: payments.mojom.PaymentHandlerHost
class BLINK_COMMON_EXPORT PaymentHandlerHostProxy
    : public PaymentHandlerHost {
 public:
  using InterfaceType = PaymentHandlerHost;

  explicit PaymentHandlerHostProxy(mojo::MessageReceiverWithResponder* receiver);
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangePaymentMethod
  void ChangePaymentMethod(PaymentHandlerMethodDataPtr method_data, ChangePaymentMethodCallback callback) final;
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangeShippingOption
  void ChangeShippingOption(const std::string& shipping_option_id, ChangeShippingOptionCallback callback) final;
  
// @generated_from: payments.mojom.PaymentHandlerHost.ChangeShippingAddress
  void ChangeShippingAddress(::payments::mojom::PaymentAddressPtr shipping_address, ChangeShippingAddressCallback callback) final;

 private:
  mojo::MessageReceiverWithResponder* receiver_;
};
class BLINK_COMMON_EXPORT PaymentHandlerHostStubDispatch {
 public:
  static bool Accept(PaymentHandlerHost* impl, mojo::Message* message);
  static bool AcceptWithResponder(
      PaymentHandlerHost* impl,
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder);
};

template <typename ImplRefTraits =
              mojo::RawPtrImplRefTraits<PaymentHandlerHost>>
class PaymentHandlerHostStub
    : public mojo::MessageReceiverWithResponderStatus {
 public:
  using ImplPointerType = typename ImplRefTraits::PointerType;

  PaymentHandlerHostStub() = default;
  ~PaymentHandlerHostStub() override = default;

  void set_sink(ImplPointerType sink) { sink_ = std::move(sink); }
  ImplPointerType& sink() { return sink_; }

  bool Accept(mojo::Message* message) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return PaymentHandlerHostStubDispatch::Accept(
        ImplRefTraits::GetRawPointer(&sink_), message);
  }

  bool AcceptWithResponder(
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return PaymentHandlerHostStubDispatch::AcceptWithResponder(
        ImplRefTraits::GetRawPointer(&sink_), message, std::move(responder));
  }

 private:
  ImplPointerType sink_;
};
class BLINK_COMMON_EXPORT PaymentHandlerHostRequestValidator : public mojo::MessageReceiver {
 public:
  bool Accept(mojo::Message* message) override;
};
class BLINK_COMMON_EXPORT PaymentHandlerHostResponseValidator : public mojo::MessageReceiver {
 public:
  bool Accept(mojo::Message* message) override;
};





// @generated_from: payments.mojom.PaymentHandlerMethodData
class BLINK_COMMON_EXPORT PaymentHandlerMethodData {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<PaymentHandlerMethodData, T>::value>;
  using DataView = PaymentHandlerMethodDataDataView;
  using Data_ = internal::PaymentHandlerMethodData_Data;

  template <typename... Args>
  static PaymentHandlerMethodDataPtr New(Args&&... args) {
    return PaymentHandlerMethodDataPtr(
        absl::in_place, std::forward<Args>(args)...);
  }

  template <typename U>
  static PaymentHandlerMethodDataPtr From(const U& u) {
    return mojo::TypeConverter<PaymentHandlerMethodDataPtr, U>::Convert(u);
  }

  template <typename U>
  U To() const {
    return mojo::TypeConverter<U, PaymentHandlerMethodData>::Convert(*this);
  }


  PaymentHandlerMethodData();

  PaymentHandlerMethodData(
      const std::string& method_name,
      const absl::optional<std::string>& stringified_data);


  ~PaymentHandlerMethodData();

  // Clone() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Clone() or copy
  // constructor/assignment are available for members.
  template <typename StructPtrType = PaymentHandlerMethodDataPtr>
  PaymentHandlerMethodDataPtr Clone() const;

  // Equals() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Equals() or == operator
  // are available for members.
  template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

  template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }
  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        PaymentHandlerMethodData::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        PaymentHandlerMethodData::DataView>(input);
  }

  // The returned Message is serialized only if the message is moved
  // cross-process or cross-language. Otherwise if the message is Deserialized
  // as the same UserType |input| will just be moved to |output| in
  // DeserializeFromMessage.
  template <typename UserType>
  static mojo::Message WrapAsMessage(UserType input) {
    return mojo::Message(std::make_unique<
        internal::PaymentHandlerMethodData_UnserializedMessageContext<
            UserType, PaymentHandlerMethodData::DataView>>(0, 0, std::move(input)),
        MOJO_CREATE_MESSAGE_FLAG_NONE);
  }

  template <typename UserType>
  static bool Deserialize(const void* data,
                          size_t data_num_bytes,
                          UserType* output) {
    mojo::Message message;
    return mojo::internal::DeserializeImpl<PaymentHandlerMethodData::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(const std::vector<uint8_t>& input,
                          UserType* output) {
    return PaymentHandlerMethodData::Deserialize(
        input.size() == 0 ? nullptr : &input.front(), input.size(), output);
  }

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    auto context = input.TakeUnserializedContext<
        internal::PaymentHandlerMethodData_UnserializedMessageContext<
            UserType, PaymentHandlerMethodData::DataView>>();
    if (context) {
      *output = std::move(context->TakeData());
      return true;
    }
    input.SerializeIfNecessary();
    return mojo::internal::DeserializeImpl<PaymentHandlerMethodData::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

  
// @generated_from: payments.mojom.PaymentHandlerMethodData.method_name
  std::string method_name;
  
// @generated_from: payments.mojom.PaymentHandlerMethodData.stringified_data
  absl::optional<std::string> stringified_data;

  // Serialise this struct into a trace.
  void WriteIntoTrace(perfetto::TracedValue traced_context) const;

 private:
  static bool Validate(const void* data,
                       mojo::internal::ValidationContext* validation_context);
};

// The comparison operators are templates, so they are only instantiated if they
// are used. Thus, the bindings generator does not need to know whether
// comparison operators are available for members.
template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
bool operator<=(const T& lhs, const T& rhs) {
  return !(rhs < lhs);
}

template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
bool operator>(const T& lhs, const T& rhs) {
  return rhs < lhs;
}

template <typename T, PaymentHandlerMethodData::EnableIfSame<T>* = nullptr>
bool operator>=(const T& lhs, const T& rhs) {
  return !(lhs < rhs);
}










// @generated_from: payments.mojom.PaymentHandlerModifier
class BLINK_COMMON_EXPORT PaymentHandlerModifier {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<PaymentHandlerModifier, T>::value>;
  using DataView = PaymentHandlerModifierDataView;
  using Data_ = internal::PaymentHandlerModifier_Data;

  template <typename... Args>
  static PaymentHandlerModifierPtr New(Args&&... args) {
    return PaymentHandlerModifierPtr(
        absl::in_place, std::forward<Args>(args)...);
  }

  template <typename U>
  static PaymentHandlerModifierPtr From(const U& u) {
    return mojo::TypeConverter<PaymentHandlerModifierPtr, U>::Convert(u);
  }

  template <typename U>
  U To() const {
    return mojo::TypeConverter<U, PaymentHandlerModifier>::Convert(*this);
  }


  PaymentHandlerModifier();

  PaymentHandlerModifier(
      ::payments::mojom::PaymentCurrencyAmountPtr total,
      PaymentHandlerMethodDataPtr method_data);

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

  ~PaymentHandlerModifier();

  // Clone() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Clone() or copy
  // constructor/assignment are available for members.
  template <typename StructPtrType = PaymentHandlerModifierPtr>
  PaymentHandlerModifierPtr Clone() const;

  // Equals() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Equals() or == operator
  // are available for members.
  template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

  template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }
  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        PaymentHandlerModifier::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        PaymentHandlerModifier::DataView>(input);
  }

  // The returned Message is serialized only if the message is moved
  // cross-process or cross-language. Otherwise if the message is Deserialized
  // as the same UserType |input| will just be moved to |output| in
  // DeserializeFromMessage.
  template <typename UserType>
  static mojo::Message WrapAsMessage(UserType input) {
    return mojo::Message(std::make_unique<
        internal::PaymentHandlerModifier_UnserializedMessageContext<
            UserType, PaymentHandlerModifier::DataView>>(0, 0, std::move(input)),
        MOJO_CREATE_MESSAGE_FLAG_NONE);
  }

  template <typename UserType>
  static bool Deserialize(const void* data,
                          size_t data_num_bytes,
                          UserType* output) {
    mojo::Message message;
    return mojo::internal::DeserializeImpl<PaymentHandlerModifier::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(const std::vector<uint8_t>& input,
                          UserType* output) {
    return PaymentHandlerModifier::Deserialize(
        input.size() == 0 ? nullptr : &input.front(), input.size(), output);
  }

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    auto context = input.TakeUnserializedContext<
        internal::PaymentHandlerModifier_UnserializedMessageContext<
            UserType, PaymentHandlerModifier::DataView>>();
    if (context) {
      *output = std::move(context->TakeData());
      return true;
    }
    input.SerializeIfNecessary();
    return mojo::internal::DeserializeImpl<PaymentHandlerModifier::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

  
// @generated_from: payments.mojom.PaymentHandlerModifier.total
  ::payments::mojom::PaymentCurrencyAmountPtr total;
  
// @generated_from: payments.mojom.PaymentHandlerModifier.method_data
  PaymentHandlerMethodDataPtr method_data;

  // Serialise this struct into a trace.
  void WriteIntoTrace(perfetto::TracedValue traced_context) const;

 private:
  static bool Validate(const void* data,
                       mojo::internal::ValidationContext* validation_context);
};

// The comparison operators are templates, so they are only instantiated if they
// are used. Thus, the bindings generator does not need to know whether
// comparison operators are available for members.
template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
bool operator<=(const T& lhs, const T& rhs) {
  return !(rhs < lhs);
}

template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
bool operator>(const T& lhs, const T& rhs) {
  return rhs < lhs;
}

template <typename T, PaymentHandlerModifier::EnableIfSame<T>* = nullptr>
bool operator>=(const T& lhs, const T& rhs) {
  return !(lhs < rhs);
}





// @generated_from: payments.mojom.PaymentRequestDetailsUpdate
class BLINK_COMMON_EXPORT PaymentRequestDetailsUpdate {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<PaymentRequestDetailsUpdate, T>::value>;
  using DataView = PaymentRequestDetailsUpdateDataView;
  using Data_ = internal::PaymentRequestDetailsUpdate_Data;

  template <typename... Args>
  static PaymentRequestDetailsUpdatePtr New(Args&&... args) {
    return PaymentRequestDetailsUpdatePtr(
        absl::in_place, std::forward<Args>(args)...);
  }

  template <typename U>
  static PaymentRequestDetailsUpdatePtr From(const U& u) {
    return mojo::TypeConverter<PaymentRequestDetailsUpdatePtr, U>::Convert(u);
  }

  template <typename U>
  U To() const {
    return mojo::TypeConverter<U, PaymentRequestDetailsUpdate>::Convert(*this);
  }


  PaymentRequestDetailsUpdate();

  PaymentRequestDetailsUpdate(
      ::payments::mojom::PaymentCurrencyAmountPtr total,
      absl::optional<std::vector<::payments::mojom::PaymentShippingOptionPtr>> shipping_options,
      absl::optional<std::vector<PaymentHandlerModifierPtr>> modifiers,
      const std::string& error,
      const absl::optional<std::string>& stringified_payment_method_errors,
      ::payments::mojom::AddressErrorsPtr shipping_address_errors);

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

  ~PaymentRequestDetailsUpdate();

  // Clone() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Clone() or copy
  // constructor/assignment are available for members.
  template <typename StructPtrType = PaymentRequestDetailsUpdatePtr>
  PaymentRequestDetailsUpdatePtr Clone() const;

  // Equals() is a template so it is only instantiated if it is used. Thus, the
  // bindings generator does not need to know whether Equals() or == operator
  // are available for members.
  template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

  template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }
  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        PaymentRequestDetailsUpdate::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        PaymentRequestDetailsUpdate::DataView>(input);
  }

  // The returned Message is serialized only if the message is moved
  // cross-process or cross-language. Otherwise if the message is Deserialized
  // as the same UserType |input| will just be moved to |output| in
  // DeserializeFromMessage.
  template <typename UserType>
  static mojo::Message WrapAsMessage(UserType input) {
    return mojo::Message(std::make_unique<
        internal::PaymentRequestDetailsUpdate_UnserializedMessageContext<
            UserType, PaymentRequestDetailsUpdate::DataView>>(0, 0, std::move(input)),
        MOJO_CREATE_MESSAGE_FLAG_NONE);
  }

  template <typename UserType>
  static bool Deserialize(const void* data,
                          size_t data_num_bytes,
                          UserType* output) {
    mojo::Message message;
    return mojo::internal::DeserializeImpl<PaymentRequestDetailsUpdate::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(const std::vector<uint8_t>& input,
                          UserType* output) {
    return PaymentRequestDetailsUpdate::Deserialize(
        input.size() == 0 ? nullptr : &input.front(), input.size(), output);
  }

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    auto context = input.TakeUnserializedContext<
        internal::PaymentRequestDetailsUpdate_UnserializedMessageContext<
            UserType, PaymentRequestDetailsUpdate::DataView>>();
    if (context) {
      *output = std::move(context->TakeData());
      return true;
    }
    input.SerializeIfNecessary();
    return mojo::internal::DeserializeImpl<PaymentRequestDetailsUpdate::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.total
  ::payments::mojom::PaymentCurrencyAmountPtr total;
  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.shipping_options
  absl::optional<std::vector<::payments::mojom::PaymentShippingOptionPtr>> shipping_options;
  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.modifiers
  absl::optional<std::vector<PaymentHandlerModifierPtr>> modifiers;
  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.error
  std::string error;
  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.stringified_payment_method_errors
  absl::optional<std::string> stringified_payment_method_errors;
  
// @generated_from: payments.mojom.PaymentRequestDetailsUpdate.shipping_address_errors
  ::payments::mojom::AddressErrorsPtr shipping_address_errors;

  // Serialise this struct into a trace.
  void WriteIntoTrace(perfetto::TracedValue traced_context) const;

 private:
  static bool Validate(const void* data,
                       mojo::internal::ValidationContext* validation_context);
};

// The comparison operators are templates, so they are only instantiated if they
// are used. Thus, the bindings generator does not need to know whether
// comparison operators are available for members.
template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
bool operator<=(const T& lhs, const T& rhs) {
  return !(rhs < lhs);
}

template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
bool operator>(const T& lhs, const T& rhs) {
  return rhs < lhs;
}

template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>* = nullptr>
bool operator>=(const T& lhs, const T& rhs) {
  return !(lhs < rhs);
}

template <typename StructPtrType>
PaymentHandlerMethodDataPtr PaymentHandlerMethodData::Clone() const {
  return New(
      mojo::Clone(method_name),
      mojo::Clone(stringified_data)
  );
}

template <typename T, PaymentHandlerMethodData::EnableIfSame<T>*>
bool PaymentHandlerMethodData::Equals(const T& other_struct) const {
  if (!mojo::Equals(this->method_name, other_struct.method_name))
    return false;
  if (!mojo::Equals(this->stringified_data, other_struct.stringified_data))
    return false;
  return true;
}

template <typename T, PaymentHandlerMethodData::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.method_name < rhs.method_name)
    return true;
  if (rhs.method_name < lhs.method_name)
    return false;
  if (lhs.stringified_data < rhs.stringified_data)
    return true;
  if (rhs.stringified_data < lhs.stringified_data)
    return false;
  return false;
}
template <typename StructPtrType>
PaymentHandlerModifierPtr PaymentHandlerModifier::Clone() const {
  return New(
      mojo::Clone(total),
      mojo::Clone(method_data)
  );
}

template <typename T, PaymentHandlerModifier::EnableIfSame<T>*>
bool PaymentHandlerModifier::Equals(const T& other_struct) const {
  if (!mojo::Equals(this->total, other_struct.total))
    return false;
  if (!mojo::Equals(this->method_data, other_struct.method_data))
    return false;
  return true;
}

template <typename T, PaymentHandlerModifier::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.total < rhs.total)
    return true;
  if (rhs.total < lhs.total)
    return false;
  if (lhs.method_data < rhs.method_data)
    return true;
  if (rhs.method_data < lhs.method_data)
    return false;
  return false;
}
template <typename StructPtrType>
PaymentRequestDetailsUpdatePtr PaymentRequestDetailsUpdate::Clone() const {
  return New(
      mojo::Clone(total),
      mojo::Clone(shipping_options),
      mojo::Clone(modifiers),
      mojo::Clone(error),
      mojo::Clone(stringified_payment_method_errors),
      mojo::Clone(shipping_address_errors)
  );
}

template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>*>
bool PaymentRequestDetailsUpdate::Equals(const T& other_struct) const {
  if (!mojo::Equals(this->total, other_struct.total))
    return false;
  if (!mojo::Equals(this->shipping_options, other_struct.shipping_options))
    return false;
  if (!mojo::Equals(this->modifiers, other_struct.modifiers))
    return false;
  if (!mojo::Equals(this->error, other_struct.error))
    return false;
  if (!mojo::Equals(this->stringified_payment_method_errors, other_struct.stringified_payment_method_errors))
    return false;
  if (!mojo::Equals(this->shipping_address_errors, other_struct.shipping_address_errors))
    return false;
  return true;
}

template <typename T, PaymentRequestDetailsUpdate::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.total < rhs.total)
    return true;
  if (rhs.total < lhs.total)
    return false;
  if (lhs.shipping_options < rhs.shipping_options)
    return true;
  if (rhs.shipping_options < lhs.shipping_options)
    return false;
  if (lhs.modifiers < rhs.modifiers)
    return true;
  if (rhs.modifiers < lhs.modifiers)
    return false;
  if (lhs.error < rhs.error)
    return true;
  if (rhs.error < lhs.error)
    return false;
  if (lhs.stringified_payment_method_errors < rhs.stringified_payment_method_errors)
    return true;
  if (rhs.stringified_payment_method_errors < lhs.stringified_payment_method_errors)
    return false;
  if (lhs.shipping_address_errors < rhs.shipping_address_errors)
    return true;
  if (rhs.shipping_address_errors < lhs.shipping_address_errors)
    return false;
  return false;
}


}  // namespace mojom
}  // namespace payments

namespace mojo {


template <>
struct BLINK_COMMON_EXPORT StructTraits<::payments::mojom::PaymentHandlerMethodData::DataView,
                                         ::payments::mojom::PaymentHandlerMethodDataPtr> {
  static bool IsNull(const ::payments::mojom::PaymentHandlerMethodDataPtr& input) { return !input; }
  static void SetToNull(::payments::mojom::PaymentHandlerMethodDataPtr* output) { output->reset(); }

  static const decltype(::payments::mojom::PaymentHandlerMethodData::method_name)& method_name(
      const ::payments::mojom::PaymentHandlerMethodDataPtr& input) {
    return input->method_name;
  }

  static const decltype(::payments::mojom::PaymentHandlerMethodData::stringified_data)& stringified_data(
      const ::payments::mojom::PaymentHandlerMethodDataPtr& input) {
    return input->stringified_data;
  }

  static bool Read(::payments::mojom::PaymentHandlerMethodData::DataView input, ::payments::mojom::PaymentHandlerMethodDataPtr* output);
};


template <>
struct BLINK_COMMON_EXPORT StructTraits<::payments::mojom::PaymentHandlerModifier::DataView,
                                         ::payments::mojom::PaymentHandlerModifierPtr> {
  static bool IsNull(const ::payments::mojom::PaymentHandlerModifierPtr& input) { return !input; }
  static void SetToNull(::payments::mojom::PaymentHandlerModifierPtr* output) { output->reset(); }

  static const decltype(::payments::mojom::PaymentHandlerModifier::total)& total(
      const ::payments::mojom::PaymentHandlerModifierPtr& input) {
    return input->total;
  }

  static const decltype(::payments::mojom::PaymentHandlerModifier::method_data)& method_data(
      const ::payments::mojom::PaymentHandlerModifierPtr& input) {
    return input->method_data;
  }

  static bool Read(::payments::mojom::PaymentHandlerModifier::DataView input, ::payments::mojom::PaymentHandlerModifierPtr* output);
};


template <>
struct BLINK_COMMON_EXPORT StructTraits<::payments::mojom::PaymentRequestDetailsUpdate::DataView,
                                         ::payments::mojom::PaymentRequestDetailsUpdatePtr> {
  static bool IsNull(const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) { return !input; }
  static void SetToNull(::payments::mojom::PaymentRequestDetailsUpdatePtr* output) { output->reset(); }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::total)& total(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->total;
  }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::shipping_options)& shipping_options(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->shipping_options;
  }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::modifiers)& modifiers(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->modifiers;
  }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::error)& error(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->error;
  }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::stringified_payment_method_errors)& stringified_payment_method_errors(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->stringified_payment_method_errors;
  }

  static const decltype(::payments::mojom::PaymentRequestDetailsUpdate::shipping_address_errors)& shipping_address_errors(
      const ::payments::mojom::PaymentRequestDetailsUpdatePtr& input) {
    return input->shipping_address_errors;
  }

  static bool Read(::payments::mojom::PaymentRequestDetailsUpdate::DataView input, ::payments::mojom::PaymentRequestDetailsUpdatePtr* output);
};

}  // namespace mojo

#endif  // THIRD_PARTY_BLINK_PUBLIC_MOJOM_PAYMENTS_PAYMENT_HANDLER_HOST_MOJOM_H_

/* Metadata comment
eyJtZXRhIjogW3siZW5kIjogMTkzNiwgImJlZ2luIjogMTkxOCwgImVkZ2UiOiAiJS9reXRoZS9l
ZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3Jw
dXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2Ui
OiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1lbnRIYW5kbGVySG9z
dCJ9fSwgeyJlbmQiOiAzNTM5LCAiYmVnaW4iOiAzNTIwLCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2Uv
Z2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6
ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJt
b2pvbSIsICJzaWduYXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudEhhbmRsZXJIb3N0LkNo
YW5nZVBheW1lbnRNZXRob2QifX0sIHsiZW5kIjogMzgzNiwgImJlZ2luIjogMzgxNiwgImVkZ2Ui
OiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZu
YW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMi
LCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1l
bnRIYW5kbGVySG9zdC5DaGFuZ2VTaGlwcGluZ09wdGlvbiJ9fSwgeyJlbmQiOiA0MTM1LCAiYmVn
aW4iOiA0MTE0LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwgInR5cGUiOiAiYW5j
aG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5nb29nbGVzb3VyY2Uu
Y29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIsICJzaWduYXR1cmUiOiAicGF5
bWVudHMubW9qb20uUGF5bWVudEhhbmRsZXJIb3N0LkNoYW5nZVNoaXBwaW5nQWRkcmVzcyJ9fSwg
eyJlbmQiOiA0NjE5LCAiYmVnaW4iOiA0NjAwLCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJh
dGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJv
bWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIs
ICJzaWduYXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudEhhbmRsZXJIb3N0LkNoYW5nZVBh
eW1lbnRNZXRob2QifX0sIHsiZW5kIjogNDgxMSwgImJlZ2luIjogNDc5MSwgImVkZ2UiOiAiJS9r
eXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjog
eyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFu
Z3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1lbnRIYW5k
bGVySG9zdC5DaGFuZ2VTaGlwcGluZ09wdGlvbiJ9fSwgeyJlbmQiOiA1MDA0LCAiYmVnaW4iOiA0
OTgzLCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2Rl
ZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2No
cm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIsICJzaWduYXR1cmUiOiAicGF5bWVudHMu
bW9qb20uUGF5bWVudEhhbmRsZXJIb3N0LkNoYW5nZVNoaXBwaW5nQWRkcmVzcyJ9fSwgeyJlbmQi
OiA2OTUyLCAiYmVnaW4iOiA2OTI4LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwg
InR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5n
b29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIsICJzaWdu
YXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudEhhbmRsZXJNZXRob2REYXRhIn19LCB7ImVu
ZCI6IDEwOTI5LCAiYmVnaW4iOiAxMDkxOCwgImVkZ2UiOiAiJS9reXRoZS9lZGdlL2dlbmVyYXRl
cyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3JwdXMiOiAiY2hyb21p
dW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2UiOiAibW9qb20iLCAi
c2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1lbnRIYW5kbGVyTWV0aG9kRGF0YS5tZXRo
b2RfbmFtZSJ9fSwgeyJlbmQiOiAxMTA1NywgImJlZ2luIjogMTEwNDEsICJlZGdlIjogIiUva3l0
aGUvZWRnZS9nZW5lcmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsi
Y29ycHVzIjogImNocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1
YWdlIjogIm1vam9tIiwgInNpZ25hdHVyZSI6ICJwYXltZW50cy5tb2pvbS5QYXltZW50SGFuZGxl
ck1ldGhvZERhdGEuc3RyaW5naWZpZWRfZGF0YSJ9fSwgeyJlbmQiOiAxMjE4MywgImJlZ2luIjog
MTIxNjEsICJlZGdlIjogIiUva3l0aGUvZWRnZS9nZW5lcmF0ZXMiLCAidHlwZSI6ICJhbmNob3Jf
ZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjogImNocm9taXVtLmdvb2dsZXNvdXJjZS5jb20v
Y2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1vam9tIiwgInNpZ25hdHVyZSI6ICJwYXltZW50
cy5tb2pvbS5QYXltZW50SGFuZGxlck1vZGlmaWVyIn19LCB7ImVuZCI6IDE2Mjc2LCAiYmVnaW4i
OiAxNjI3MSwgImVkZ2UiOiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hv
cl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNv
bS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1l
bnRzLm1vam9tLlBheW1lbnRIYW5kbGVyTW9kaWZpZXIudG90YWwifX0sIHsiZW5kIjogMTYzOTIs
ICJiZWdpbiI6IDE2MzgxLCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2VuZXJhdGVzIiwgInR5cGUi
OiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJjaHJvbWl1bS5nb29nbGVz
b3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pvbSIsICJzaWduYXR1cmUi
OiAicGF5bWVudHMubW9qb20uUGF5bWVudEhhbmRsZXJNb2RpZmllci5tZXRob2RfZGF0YSJ9fSwg
eyJlbmQiOiAxNzUxNSwgImJlZ2luIjogMTc0ODgsICJlZGdlIjogIiUva3l0aGUvZWRnZS9nZW5l
cmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjogImNo
cm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1vam9t
IiwgInNpZ25hdHVyZSI6ICJwYXltZW50cy5tb2pvbS5QYXltZW50UmVxdWVzdERldGFpbHNVcGRh
dGUifX0sIHsiZW5kIjogMjIwNTAsICJiZWdpbiI6IDIyMDQ1LCAiZWRnZSI6ICIlL2t5dGhlL2Vk
Z2UvZ2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1
cyI6ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6
ICJtb2pvbSIsICJzaWduYXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudFJlcXVlc3REZXRh
aWxzVXBkYXRlLnRvdGFsIn19LCB7ImVuZCI6IDIyMjI2LCAiYmVnaW4iOiAyMjIxMCwgImVkZ2Ui
OiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZu
YW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMi
LCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1l
bnRSZXF1ZXN0RGV0YWlsc1VwZGF0ZS5zaGlwcGluZ19vcHRpb25zIn19LCB7ImVuZCI6IDIyMzcw
LCAiYmVnaW4iOiAyMjM2MSwgImVkZ2UiOiAiJS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBl
IjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xl
c291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJl
IjogInBheW1lbnRzLm1vam9tLlBheW1lbnRSZXF1ZXN0RGV0YWlsc1VwZGF0ZS5tb2RpZmllcnMi
fX0sIHsiZW5kIjogMjI0NjMsICJiZWdpbiI6IDIyNDU4LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2Uv
Z2VuZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6
ICJjaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJt
b2pvbSIsICJzaWduYXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudFJlcXVlc3REZXRhaWxz
VXBkYXRlLmVycm9yIn19LCB7ImVuZCI6IDIyNjI4LCAiYmVnaW4iOiAyMjU5NSwgImVkZ2UiOiAi
JS9reXRoZS9lZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1l
IjogeyJjb3JwdXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAi
bGFuZ3VhZ2UiOiAibW9qb20iLCAic2lnbmF0dXJlIjogInBheW1lbnRzLm1vam9tLlBheW1lbnRS
ZXF1ZXN0RGV0YWlsc1VwZGF0ZS5zdHJpbmdpZmllZF9wYXltZW50X21ldGhvZF9lcnJvcnMifX0s
IHsiZW5kIjogMjI3ODEsICJiZWdpbiI6IDIyNzU4LCAiZWRnZSI6ICIlL2t5dGhlL2VkZ2UvZ2Vu
ZXJhdGVzIiwgInR5cGUiOiAiYW5jaG9yX2RlZmluZXMiLCAidm5hbWUiOiB7ImNvcnB1cyI6ICJj
aHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYyIsICJsYW5ndWFnZSI6ICJtb2pv
bSIsICJzaWduYXR1cmUiOiAicGF5bWVudHMubW9qb20uUGF5bWVudFJlcXVlc3REZXRhaWxzVXBk
YXRlLnNoaXBwaW5nX2FkZHJlc3NfZXJyb3JzIn19XSwgInR5cGUiOiAia3l0aGUwIn0=
*/