// services/viz/public/mojom/compositing/animation.mojom.h is auto generated by mojom_bindings_generator.py, do not edit

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

#ifndef SERVICES_VIZ_PUBLIC_MOJOM_COMPOSITING_ANIMATION_MOJOM_H_
#define SERVICES_VIZ_PUBLIC_MOJOM_COMPOSITING_ANIMATION_MOJOM_H_

#include <stdint.h>

#include <limits>
#include <optional>
#include <type_traits>
#include <utility>
#include "mojo/public/cpp/bindings/clone_traits.h"
#include "mojo/public/cpp/bindings/equals_traits.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 "mojo/public/cpp/bindings/lib/serialization.h"

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

#include "services/viz/public/mojom/compositing/animation.mojom-features.h"  // IWYU pragma: export
#include "services/viz/public/mojom/compositing/animation.mojom-shared.h"  // IWYU pragma: export
#include "services/viz/public/mojom/compositing/animation.mojom-forward.h"  // IWYU pragma: export
#include "cc/mojom/element_id.mojom.h"
#include "mojo/public/mojom/base/time.mojom.h"
#include "skia/public/mojom/skcolor.mojom.h"
#include "ui/gfx/geometry/mojom/geometry.mojom.h"
#include "ui/gfx/mojom/transform.mojom.h"
#include <string>
#include <vector>








namespace viz::mojom {





class  CubicBezierTimingFunction {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<CubicBezierTimingFunction, T>::value>;
  using DataView = CubicBezierTimingFunctionDataView;
  using Data_ = internal::CubicBezierTimingFunction_Data;

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

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

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


  CubicBezierTimingFunction();

  CubicBezierTimingFunction(
      double x1,
      double y1,
      double x2,
      double y2);


  ~CubicBezierTimingFunction();

  // 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 = CubicBezierTimingFunctionPtr>
  CubicBezierTimingFunctionPtr 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, CubicBezierTimingFunction::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

  template <typename T, CubicBezierTimingFunction::EnableIfSame<T>* = nullptr>
  bool operator!=(const T& rhs) const { return !operator==(rhs); }
  size_t Hash(size_t seed) const;

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        CubicBezierTimingFunction::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        CubicBezierTimingFunction::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        CubicBezierTimingFunction::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::CubicBezierTimingFunction_UnserializedMessageContext<
            UserType, CubicBezierTimingFunction::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<CubicBezierTimingFunction::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return CubicBezierTimingFunction::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  double x1;
  
  double y1;
  
  double x2;
  
  double y2;

  // 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, CubicBezierTimingFunction::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  StepsTimingFunction {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<StepsTimingFunction, T>::value>;
  using DataView = StepsTimingFunctionDataView;
  using Data_ = internal::StepsTimingFunction_Data;

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

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

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


  StepsTimingFunction();

  StepsTimingFunction(
      uint32_t num_steps,
      TimingStepPosition step_position);


  ~StepsTimingFunction();

  // 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 = StepsTimingFunctionPtr>
  StepsTimingFunctionPtr 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, StepsTimingFunction::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

  template <typename T, StepsTimingFunction::EnableIfSame<T>* = nullptr>
  bool operator!=(const T& rhs) const { return !operator==(rhs); }
  size_t Hash(size_t seed) const;

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        StepsTimingFunction::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        StepsTimingFunction::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        StepsTimingFunction::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::StepsTimingFunction_UnserializedMessageContext<
            UserType, StepsTimingFunction::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<StepsTimingFunction::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return StepsTimingFunction::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  uint32_t num_steps;
  
  TimingStepPosition step_position;

  // 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, StepsTimingFunction::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  LinearEasingPoint {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<LinearEasingPoint, T>::value>;
  using DataView = LinearEasingPointDataView;
  using Data_ = internal::LinearEasingPoint_Data;

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

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

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


  LinearEasingPoint();

  LinearEasingPoint(
      double in,
      double out);


  ~LinearEasingPoint();

  // 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 = LinearEasingPointPtr>
  LinearEasingPointPtr 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, LinearEasingPoint::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

  template <typename T, LinearEasingPoint::EnableIfSame<T>* = nullptr>
  bool operator!=(const T& rhs) const { return !operator==(rhs); }
  size_t Hash(size_t seed) const;

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        LinearEasingPoint::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        LinearEasingPoint::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        LinearEasingPoint::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::LinearEasingPoint_UnserializedMessageContext<
            UserType, LinearEasingPoint::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<LinearEasingPoint::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return LinearEasingPoint::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  double in;
  
  double out;

  // 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, LinearEasingPoint::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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










class  TimingFunction {
 public:
  using DataView = TimingFunctionDataView;
  using Data_ = internal::TimingFunction_Data;
  using Tag = Data_::TimingFunction_Tag;

  template <typename... Args>
  static TimingFunctionPtr New(Args&&... args) {
    static_assert(
        sizeof...(args) < 0,
        "Do not use Union::New(); to create a union of a given subtype, use "
        "New<SubType>(), not New() followed by set_<sub_type>(). To represent "
        "an empty union, mark the field or parameter as nullable in the mojom "
        "definition.");
    return nullptr;
  }

  // Construct an instance holding |cubic_bezier|.
  static TimingFunctionPtr NewCubicBezier(
      CubicBezierTimingFunctionPtr value);
  // Construct an instance holding |steps|.
  static TimingFunctionPtr NewSteps(
      StepsTimingFunctionPtr value);
  // Construct an instance holding |linear|.
  static TimingFunctionPtr NewLinear(
      std::vector<LinearEasingPointPtr> value);

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

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

  // Delete the copy constructor and copy assignment operators because `data_`
  // contains raw pointers that must not be copied.
  TimingFunction(const TimingFunction& other) = delete;
  TimingFunction& operator=(const TimingFunction& other) = delete;

  // 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 UnionPtrType = TimingFunctionPtr>
  TimingFunctionPtr 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,
            typename std::enable_if<std::is_same<
                T, TimingFunction>::value>::type* = nullptr>
  bool Equals(const T& other) const;

  template <typename T,
            typename std::enable_if<std::is_same<
                T, TimingFunction>::value>::type* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }

  Tag which() const {
    return tag_;
  }

  bool is_cubic_bezier() const { return tag_ == Tag::kCubicBezier; }
  const CubicBezierTimingFunctionPtr& get_cubic_bezier() const {
    CHECK(tag_ == Tag::kCubicBezier);
    return data_.cubic_bezier;
  }
  CubicBezierTimingFunctionPtr& get_cubic_bezier() {
    CHECK(tag_ == Tag::kCubicBezier);
    return data_.cubic_bezier;
  }
  void set_cubic_bezier(CubicBezierTimingFunctionPtr cubic_bezier);

  bool is_steps() const { return tag_ == Tag::kSteps; }
  const StepsTimingFunctionPtr& get_steps() const {
    CHECK(tag_ == Tag::kSteps);
    return data_.steps;
  }
  StepsTimingFunctionPtr& get_steps() {
    CHECK(tag_ == Tag::kSteps);
    return data_.steps;
  }
  void set_steps(StepsTimingFunctionPtr steps);

  bool is_linear() const { return tag_ == Tag::kLinear; }
  const std::vector<LinearEasingPointPtr>& get_linear() const {
    CHECK(tag_ == Tag::kLinear);
    return data_.linear;
  }
  std::vector<LinearEasingPointPtr>& get_linear() {
    CHECK(tag_ == Tag::kLinear);
    return data_.linear;
  }
  void set_linear(std::vector<LinearEasingPointPtr> linear);

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

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    return mojo::internal::DeserializeImpl<TimingFunction::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

 private:
  template <typename T>
  friend class ::mojo::InlinedStructPtr;
  template <typename T>
  friend class ::mojo::StructPtr;

  union Union_ {
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kCubicBezier)>,
        CubicBezierTimingFunctionPtr value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kSteps)>,
        StepsTimingFunctionPtr value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kLinear)>,
        std::vector<LinearEasingPointPtr> value);
    // The contents of the union are explicitly destroyed by `DestroyActive()`.
    ~Union_() {}

    CubicBezierTimingFunctionPtr cubic_bezier;
    StepsTimingFunctionPtr steps;
    std::vector<LinearEasingPointPtr> linear;
  };

  TimingFunction(
      std::in_place_index_t<static_cast<size_t>(Tag::kCubicBezier)>,
      CubicBezierTimingFunctionPtr value);
  TimingFunction(
      std::in_place_index_t<static_cast<size_t>(Tag::kSteps)>,
      StepsTimingFunctionPtr value);
  TimingFunction(
      std::in_place_index_t<static_cast<size_t>(Tag::kLinear)>,
      std::vector<LinearEasingPointPtr> value);

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

  void DestroyActive();
  Tag tag_;
  Union_ data_;
};



class  TransformOperation {
 public:
  using DataView = TransformOperationDataView;
  using Data_ = internal::TransformOperation_Data;
  using Tag = Data_::TransformOperation_Tag;

  template <typename... Args>
  static TransformOperationPtr New(Args&&... args) {
    static_assert(
        sizeof...(args) < 0,
        "Do not use Union::New(); to create a union of a given subtype, use "
        "New<SubType>(), not New() followed by set_<sub_type>(). To represent "
        "an empty union, mark the field or parameter as nullable in the mojom "
        "definition.");
    return nullptr;
  }

  // Construct an instance holding |identity|.
  static TransformOperationPtr NewIdentity(
      bool value);
  // Construct an instance holding |perspective_depth|.
  static TransformOperationPtr NewPerspectiveDepth(
      float value);
  // Construct an instance holding |skew|.
  static TransformOperationPtr NewSkew(
      const ::gfx::Vector2dF& value);
  // Construct an instance holding |scale|.
  static TransformOperationPtr NewScale(
      const ::gfx::Vector3dF& value);
  // Construct an instance holding |translate|.
  static TransformOperationPtr NewTranslate(
      const ::gfx::Vector3dF& value);
  // Construct an instance holding |rotate|.
  static TransformOperationPtr NewRotate(
      AxisAnglePtr value);
  // Construct an instance holding |matrix|.
  static TransformOperationPtr NewMatrix(
      const ::gfx::Transform& value);

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

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

  // Delete the copy constructor and copy assignment operators because `data_`
  // contains raw pointers that must not be copied.
  TransformOperation(const TransformOperation& other) = delete;
  TransformOperation& operator=(const TransformOperation& other) = delete;

  // 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 UnionPtrType = TransformOperationPtr>
  TransformOperationPtr 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,
            typename std::enable_if<std::is_same<
                T, TransformOperation>::value>::type* = nullptr>
  bool Equals(const T& other) const;

  template <typename T,
            typename std::enable_if<std::is_same<
                T, TransformOperation>::value>::type* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }

  Tag which() const {
    return tag_;
  }

  bool is_identity() const { return tag_ == Tag::kIdentity; }
  bool get_identity() const {
    CHECK(tag_ == Tag::kIdentity);
    return data_.identity;
  }
  void set_identity(bool identity);

  bool is_perspective_depth() const { return tag_ == Tag::kPerspectiveDepth; }
  float get_perspective_depth() const {
    CHECK(tag_ == Tag::kPerspectiveDepth);
    return data_.perspective_depth;
  }
  void set_perspective_depth(float perspective_depth);

  bool is_skew() const { return tag_ == Tag::kSkew; }
  const ::gfx::Vector2dF& get_skew() const {
    CHECK(tag_ == Tag::kSkew);
    return data_.skew;
  }
  ::gfx::Vector2dF& get_skew() {
    CHECK(tag_ == Tag::kSkew);
    return data_.skew;
  }
  void set_skew(const ::gfx::Vector2dF& skew);

  bool is_scale() const { return tag_ == Tag::kScale; }
  const ::gfx::Vector3dF& get_scale() const {
    CHECK(tag_ == Tag::kScale);
    return data_.scale;
  }
  ::gfx::Vector3dF& get_scale() {
    CHECK(tag_ == Tag::kScale);
    return data_.scale;
  }
  void set_scale(const ::gfx::Vector3dF& scale);

  bool is_translate() const { return tag_ == Tag::kTranslate; }
  const ::gfx::Vector3dF& get_translate() const {
    CHECK(tag_ == Tag::kTranslate);
    return data_.translate;
  }
  ::gfx::Vector3dF& get_translate() {
    CHECK(tag_ == Tag::kTranslate);
    return data_.translate;
  }
  void set_translate(const ::gfx::Vector3dF& translate);

  bool is_rotate() const { return tag_ == Tag::kRotate; }
  const AxisAnglePtr& get_rotate() const {
    CHECK(tag_ == Tag::kRotate);
    return data_.rotate;
  }
  AxisAnglePtr& get_rotate() {
    CHECK(tag_ == Tag::kRotate);
    return data_.rotate;
  }
  void set_rotate(AxisAnglePtr rotate);

  bool is_matrix() const { return tag_ == Tag::kMatrix; }
  const ::gfx::Transform& get_matrix() const {
    CHECK(tag_ == Tag::kMatrix);
    return data_.matrix;
  }
  ::gfx::Transform& get_matrix() {
    CHECK(tag_ == Tag::kMatrix);
    return data_.matrix;
  }
  void set_matrix(const ::gfx::Transform& matrix);

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

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    return mojo::internal::DeserializeImpl<TransformOperation::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

 private:
  template <typename T>
  friend class ::mojo::InlinedStructPtr;
  template <typename T>
  friend class ::mojo::StructPtr;

  union Union_ {
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kIdentity)>,
        bool value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kPerspectiveDepth)>,
        float value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kSkew)>,
        const ::gfx::Vector2dF& value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kScale)>,
        const ::gfx::Vector3dF& value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kTranslate)>,
        const ::gfx::Vector3dF& value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kRotate)>,
        AxisAnglePtr value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kMatrix)>,
        const ::gfx::Transform& value);
    // The contents of the union are explicitly destroyed by `DestroyActive()`.
    ~Union_() {}

    bool identity;
    float perspective_depth;
    ::gfx::Vector2dF skew;
    ::gfx::Vector3dF scale;
    ::gfx::Vector3dF translate;
    AxisAnglePtr rotate;
    ::gfx::Transform matrix;
  };

  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kIdentity)>,
      bool value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kPerspectiveDepth)>,
      float value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kSkew)>,
      const ::gfx::Vector2dF& value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kScale)>,
      const ::gfx::Vector3dF& value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kTranslate)>,
      const ::gfx::Vector3dF& value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kRotate)>,
      AxisAnglePtr value);
  TransformOperation(
      std::in_place_index_t<static_cast<size_t>(Tag::kMatrix)>,
      const ::gfx::Transform& value);

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

  void DestroyActive();
  Tag tag_;
  Union_ data_;
};



class  AnimationKeyframeValue {
 public:
  using DataView = AnimationKeyframeValueDataView;
  using Data_ = internal::AnimationKeyframeValue_Data;
  using Tag = Data_::AnimationKeyframeValue_Tag;

  template <typename... Args>
  static AnimationKeyframeValuePtr New(Args&&... args) {
    static_assert(
        sizeof...(args) < 0,
        "Do not use Union::New(); to create a union of a given subtype, use "
        "New<SubType>(), not New() followed by set_<sub_type>(). To represent "
        "an empty union, mark the field or parameter as nullable in the mojom "
        "definition.");
    return nullptr;
  }

  // Construct an instance holding |scalar|.
  static AnimationKeyframeValuePtr NewScalar(
      float value);
  // Construct an instance holding |color|.
  static AnimationKeyframeValuePtr NewColor(
      ::SkColor value);
  // Construct an instance holding |size|.
  static AnimationKeyframeValuePtr NewSize(
      const ::gfx::SizeF& value);
  // Construct an instance holding |rect|.
  static AnimationKeyframeValuePtr NewRect(
      const ::gfx::Rect& value);
  // Construct an instance holding |transform|.
  static AnimationKeyframeValuePtr NewTransform(
      std::vector<TransformOperationPtr> value);

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

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

  // Delete the copy constructor and copy assignment operators because `data_`
  // contains raw pointers that must not be copied.
  AnimationKeyframeValue(const AnimationKeyframeValue& other) = delete;
  AnimationKeyframeValue& operator=(const AnimationKeyframeValue& other) = delete;

  // 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 UnionPtrType = AnimationKeyframeValuePtr>
  AnimationKeyframeValuePtr 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,
            typename std::enable_if<std::is_same<
                T, AnimationKeyframeValue>::value>::type* = nullptr>
  bool Equals(const T& other) const;

  template <typename T,
            typename std::enable_if<std::is_same<
                T, AnimationKeyframeValue>::value>::type* = nullptr>
  bool operator==(const T& rhs) const { return Equals(rhs); }

  Tag which() const {
    return tag_;
  }

  bool is_scalar() const { return tag_ == Tag::kScalar; }
  float get_scalar() const {
    CHECK(tag_ == Tag::kScalar);
    return data_.scalar;
  }
  void set_scalar(float scalar);

  bool is_color() const { return tag_ == Tag::kColor; }
  const ::SkColor& get_color() const {
    CHECK(tag_ == Tag::kColor);
    return data_.color;
  }
  ::SkColor& get_color() {
    CHECK(tag_ == Tag::kColor);
    return data_.color;
  }
  void set_color(::SkColor color);

  bool is_size() const { return tag_ == Tag::kSize; }
  const ::gfx::SizeF& get_size() const {
    CHECK(tag_ == Tag::kSize);
    return data_.size;
  }
  ::gfx::SizeF& get_size() {
    CHECK(tag_ == Tag::kSize);
    return data_.size;
  }
  void set_size(const ::gfx::SizeF& size);

  bool is_rect() const { return tag_ == Tag::kRect; }
  const ::gfx::Rect& get_rect() const {
    CHECK(tag_ == Tag::kRect);
    return data_.rect;
  }
  ::gfx::Rect& get_rect() {
    CHECK(tag_ == Tag::kRect);
    return data_.rect;
  }
  void set_rect(const ::gfx::Rect& rect);

  bool is_transform() const { return tag_ == Tag::kTransform; }
  const std::vector<TransformOperationPtr>& get_transform() const {
    CHECK(tag_ == Tag::kTransform);
    return data_.transform;
  }
  std::vector<TransformOperationPtr>& get_transform() {
    CHECK(tag_ == Tag::kTransform);
    return data_.transform;
  }
  void set_transform(std::vector<TransformOperationPtr> transform);

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

  template <typename UserType>
  static bool DeserializeFromMessage(mojo::Message input,
                                     UserType* output) {
    return mojo::internal::DeserializeImpl<AnimationKeyframeValue::DataView>(
        input, input.payload(), input.payload_num_bytes(), output, Validate);
  }

 private:
  template <typename T>
  friend class ::mojo::InlinedStructPtr;
  template <typename T>
  friend class ::mojo::StructPtr;

  union Union_ {
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kScalar)>,
        float value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kColor)>,
        ::SkColor value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kSize)>,
        const ::gfx::SizeF& value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kRect)>,
        const ::gfx::Rect& value);
    Union_(
        std::in_place_index_t<static_cast<size_t>(Tag::kTransform)>,
        std::vector<TransformOperationPtr> value);
    // The contents of the union are explicitly destroyed by `DestroyActive()`.
    ~Union_() {}

    float scalar;
    ::SkColor color;
    ::gfx::SizeF size;
    ::gfx::Rect rect;
    std::vector<TransformOperationPtr> transform;
  };

  AnimationKeyframeValue(
      std::in_place_index_t<static_cast<size_t>(Tag::kScalar)>,
      float value);
  AnimationKeyframeValue(
      std::in_place_index_t<static_cast<size_t>(Tag::kColor)>,
      ::SkColor value);
  AnimationKeyframeValue(
      std::in_place_index_t<static_cast<size_t>(Tag::kSize)>,
      const ::gfx::SizeF& value);
  AnimationKeyframeValue(
      std::in_place_index_t<static_cast<size_t>(Tag::kRect)>,
      const ::gfx::Rect& value);
  AnimationKeyframeValue(
      std::in_place_index_t<static_cast<size_t>(Tag::kTransform)>,
      std::vector<TransformOperationPtr> value);

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

  void DestroyActive();
  Tag tag_;
  Union_ data_;
};








class  AxisAngle {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<AxisAngle, T>::value>;
  using DataView = AxisAngleDataView;
  using Data_ = internal::AxisAngle_Data;

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

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

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


  AxisAngle();

  AxisAngle(
      const ::gfx::Vector3dF& axis,
      float angle);


  ~AxisAngle();

  // 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 = AxisAnglePtr>
  AxisAnglePtr 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, AxisAngle::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

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

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AxisAngle::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AxisAngle::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        AxisAngle::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::AxisAngle_UnserializedMessageContext<
            UserType, AxisAngle::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<AxisAngle::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return AxisAngle::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  ::gfx::Vector3dF axis;
  
  float angle;

  // 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, AxisAngle::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  AnimationKeyframe {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<AnimationKeyframe, T>::value>;
  using DataView = AnimationKeyframeDataView;
  using Data_ = internal::AnimationKeyframe_Data;

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

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

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


  AnimationKeyframe();

  AnimationKeyframe(
      AnimationKeyframeValuePtr value,
      ::base::TimeDelta start_time,
      TimingFunctionPtr timing_function);

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

  ~AnimationKeyframe();

  // 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 = AnimationKeyframePtr>
  AnimationKeyframePtr 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, AnimationKeyframe::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

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

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationKeyframe::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationKeyframe::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        AnimationKeyframe::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::AnimationKeyframe_UnserializedMessageContext<
            UserType, AnimationKeyframe::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<AnimationKeyframe::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return AnimationKeyframe::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  AnimationKeyframeValuePtr value;
  
  ::base::TimeDelta start_time;
  
  TimingFunctionPtr timing_function;

  // 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, AnimationKeyframe::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  AnimationKeyframeModel {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<AnimationKeyframeModel, T>::value>;
  using DataView = AnimationKeyframeModelDataView;
  using Data_ = internal::AnimationKeyframeModel_Data;

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

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

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


  AnimationKeyframeModel();

  AnimationKeyframeModel(
      int32_t id,
      int32_t group_id,
      int32_t target_property_type,
      ::cc::ElementId element_id,
      TimingFunctionPtr timing_function,
      std::vector<AnimationKeyframePtr> keyframes,
      double scaled_duration,
      AnimationDirection direction,
      AnimationFillMode fill_mode,
      double playback_rate,
      double iterations,
      double iteration_start,
      ::base::TimeDelta start_delay,
      std::optional<::base::TimeDelta> hold_time);

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

  ~AnimationKeyframeModel();

  // 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 = AnimationKeyframeModelPtr>
  AnimationKeyframeModelPtr 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, AnimationKeyframeModel::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

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

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationKeyframeModel::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationKeyframeModel::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        AnimationKeyframeModel::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::AnimationKeyframeModel_UnserializedMessageContext<
            UserType, AnimationKeyframeModel::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<AnimationKeyframeModel::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return AnimationKeyframeModel::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  int32_t id;
  
  int32_t group_id;
  
  int32_t target_property_type;
  
  ::cc::ElementId element_id;
  
  TimingFunctionPtr timing_function;
  
  std::vector<AnimationKeyframePtr> keyframes;
  
  double scaled_duration;
  
  AnimationDirection direction;
  
  AnimationFillMode fill_mode;
  
  double playback_rate;
  
  double iterations;
  
  double iteration_start;
  
  ::base::TimeDelta start_delay;
  
  std::optional<::base::TimeDelta> hold_time;

  // 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, AnimationKeyframeModel::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  Animation {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<Animation, T>::value>;
  using DataView = AnimationDataView;
  using Data_ = internal::Animation_Data;

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

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

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


  Animation();

  Animation(
      int32_t id,
      ::cc::ElementId element_id,
      std::vector<AnimationKeyframeModelPtr> keyframe_models);

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

  ~Animation();

  // 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 = AnimationPtr>
  AnimationPtr 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, Animation::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

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

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        Animation::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        Animation::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        Animation::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::Animation_UnserializedMessageContext<
            UserType, Animation::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<Animation::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return Animation::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  int32_t id;
  
  ::cc::ElementId element_id;
  
  std::vector<AnimationKeyframeModelPtr> keyframe_models;

  // 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, Animation::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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





class  AnimationTimeline {
 public:
  template <typename T>
  using EnableIfSame = std::enable_if_t<std::is_same<AnimationTimeline, T>::value>;
  using DataView = AnimationTimelineDataView;
  using Data_ = internal::AnimationTimeline_Data;

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

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

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


  AnimationTimeline();

  AnimationTimeline(
      int32_t id,
      std::vector<AnimationPtr> new_animations,
      std::vector<int32_t> removed_animations);

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

  ~AnimationTimeline();

  // 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 = AnimationTimelinePtr>
  AnimationTimelinePtr 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, AnimationTimeline::EnableIfSame<T>* = nullptr>
  bool Equals(const T& other) const;

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

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

  template <mojo::internal::SendValidation send_validation, typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationTimeline::DataView, std::vector<uint8_t>, send_validation>(input);
  }

  template <typename UserType>
  static std::vector<uint8_t> Serialize(UserType* input) {
    return mojo::internal::SerializeImpl<
        AnimationTimeline::DataView, std::vector<uint8_t>>(input);
  }

  template <typename UserType>
  static mojo::Message SerializeAsMessage(UserType* input) {
    return mojo::internal::SerializeAsMessageImpl<
        AnimationTimeline::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::AnimationTimeline_UnserializedMessageContext<
            UserType, AnimationTimeline::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<AnimationTimeline::DataView>(
        message, data, data_num_bytes, output, Validate);
  }

  template <typename UserType>
  static bool Deserialize(base::span<const uint8_t> input,
                          UserType* output) {
    return AnimationTimeline::Deserialize(
        input.empty() ? nullptr : input.data(), input.size(), output);
  }

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

  
  int32_t id;
  
  std::vector<AnimationPtr> new_animations;
  
  std::vector<int32_t> removed_animations;

  // 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, AnimationTimeline::EnableIfSame<T>* = nullptr>
bool operator<(const T& lhs, const T& rhs);

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

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

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

template <typename UnionPtrType>
TimingFunctionPtr TimingFunction::Clone() const {
  switch (tag_) {
    case Tag::kCubicBezier:
      return NewCubicBezier(
          mojo::Clone(data_.cubic_bezier));
    case Tag::kSteps:
      return NewSteps(
          mojo::Clone(data_.steps));
    case Tag::kLinear:
      return NewLinear(
          mojo::Clone(data_.linear));
  }
  return nullptr;
}

template <typename T,
          typename std::enable_if<std::is_same<
              T, TimingFunction>::value>::type*>
bool TimingFunction::Equals(const T& other) const {
  if (tag_ != other.which())
    return false;

  switch (tag_) {
    case Tag::kCubicBezier:
      return mojo::Equals(data_.cubic_bezier, other.data_.cubic_bezier);
    case Tag::kSteps:
      return mojo::Equals(data_.steps, other.data_.steps);
    case Tag::kLinear:
      return mojo::Equals(data_.linear, other.data_.linear);
  }

  return false;
}
template <typename UnionPtrType>
TransformOperationPtr TransformOperation::Clone() const {
  switch (tag_) {
    case Tag::kIdentity:
      return NewIdentity(
          mojo::Clone(data_.identity));
    case Tag::kPerspectiveDepth:
      return NewPerspectiveDepth(
          mojo::Clone(data_.perspective_depth));
    case Tag::kSkew:
      return NewSkew(
          mojo::Clone(data_.skew));
    case Tag::kScale:
      return NewScale(
          mojo::Clone(data_.scale));
    case Tag::kTranslate:
      return NewTranslate(
          mojo::Clone(data_.translate));
    case Tag::kRotate:
      return NewRotate(
          mojo::Clone(data_.rotate));
    case Tag::kMatrix:
      return NewMatrix(
          mojo::Clone(data_.matrix));
  }
  return nullptr;
}

template <typename T,
          typename std::enable_if<std::is_same<
              T, TransformOperation>::value>::type*>
bool TransformOperation::Equals(const T& other) const {
  if (tag_ != other.which())
    return false;

  switch (tag_) {
    case Tag::kIdentity:
      return mojo::Equals(data_.identity, other.data_.identity);
    case Tag::kPerspectiveDepth:
      return mojo::Equals(data_.perspective_depth, other.data_.perspective_depth);
    case Tag::kSkew:
      return mojo::Equals(data_.skew, other.data_.skew);
    case Tag::kScale:
      return mojo::Equals(data_.scale, other.data_.scale);
    case Tag::kTranslate:
      return mojo::Equals(data_.translate, other.data_.translate);
    case Tag::kRotate:
      return mojo::Equals(data_.rotate, other.data_.rotate);
    case Tag::kMatrix:
      return mojo::Equals(data_.matrix, other.data_.matrix);
  }

  return false;
}
template <typename UnionPtrType>
AnimationKeyframeValuePtr AnimationKeyframeValue::Clone() const {
  switch (tag_) {
    case Tag::kScalar:
      return NewScalar(
          mojo::Clone(data_.scalar));
    case Tag::kColor:
      return NewColor(
          mojo::Clone(data_.color));
    case Tag::kSize:
      return NewSize(
          mojo::Clone(data_.size));
    case Tag::kRect:
      return NewRect(
          mojo::Clone(data_.rect));
    case Tag::kTransform:
      return NewTransform(
          mojo::Clone(data_.transform));
  }
  return nullptr;
}

template <typename T,
          typename std::enable_if<std::is_same<
              T, AnimationKeyframeValue>::value>::type*>
bool AnimationKeyframeValue::Equals(const T& other) const {
  if (tag_ != other.which())
    return false;

  switch (tag_) {
    case Tag::kScalar:
      return mojo::Equals(data_.scalar, other.data_.scalar);
    case Tag::kColor:
      return mojo::Equals(data_.color, other.data_.color);
    case Tag::kSize:
      return mojo::Equals(data_.size, other.data_.size);
    case Tag::kRect:
      return mojo::Equals(data_.rect, other.data_.rect);
    case Tag::kTransform:
      return mojo::Equals(data_.transform, other.data_.transform);
  }

  return false;
}
template <typename StructPtrType>
CubicBezierTimingFunctionPtr CubicBezierTimingFunction::Clone() const {
  return New(
      mojo::Clone(x1),
      mojo::Clone(y1),
      mojo::Clone(x2),
      mojo::Clone(y2)
  );
}

template <typename T, CubicBezierTimingFunction::EnableIfSame<T>*>
bool CubicBezierTimingFunction::Equals(const T& other_struct) const {
  if (!mojo::Equals(this->x1, other_struct.x1))
    return false;
  if (!mojo::Equals(this->y1, other_struct.y1))
    return false;
  if (!mojo::Equals(this->x2, other_struct.x2))
    return false;
  if (!mojo::Equals(this->y2, other_struct.y2))
    return false;
  return true;
}

template <typename T, CubicBezierTimingFunction::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.x1 < rhs.x1)
    return true;
  if (rhs.x1 < lhs.x1)
    return false;
  if (lhs.y1 < rhs.y1)
    return true;
  if (rhs.y1 < lhs.y1)
    return false;
  if (lhs.x2 < rhs.x2)
    return true;
  if (rhs.x2 < lhs.x2)
    return false;
  if (lhs.y2 < rhs.y2)
    return true;
  if (rhs.y2 < lhs.y2)
    return false;
  return false;
}
template <typename StructPtrType>
StepsTimingFunctionPtr StepsTimingFunction::Clone() const {
  return New(
      mojo::Clone(num_steps),
      mojo::Clone(step_position)
  );
}

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

template <typename T, StepsTimingFunction::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.num_steps < rhs.num_steps)
    return true;
  if (rhs.num_steps < lhs.num_steps)
    return false;
  if (lhs.step_position < rhs.step_position)
    return true;
  if (rhs.step_position < lhs.step_position)
    return false;
  return false;
}
template <typename StructPtrType>
LinearEasingPointPtr LinearEasingPoint::Clone() const {
  return New(
      mojo::Clone(in),
      mojo::Clone(out)
  );
}

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

template <typename T, LinearEasingPoint::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.in < rhs.in)
    return true;
  if (rhs.in < lhs.in)
    return false;
  if (lhs.out < rhs.out)
    return true;
  if (rhs.out < lhs.out)
    return false;
  return false;
}
template <typename StructPtrType>
AxisAnglePtr AxisAngle::Clone() const {
  return New(
      mojo::Clone(axis),
      mojo::Clone(angle)
  );
}

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

template <typename T, AxisAngle::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.axis < rhs.axis)
    return true;
  if (rhs.axis < lhs.axis)
    return false;
  if (lhs.angle < rhs.angle)
    return true;
  if (rhs.angle < lhs.angle)
    return false;
  return false;
}
template <typename StructPtrType>
AnimationKeyframePtr AnimationKeyframe::Clone() const {
  return New(
      mojo::Clone(value),
      mojo::Clone(start_time),
      mojo::Clone(timing_function)
  );
}

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

template <typename T, AnimationKeyframe::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.value < rhs.value)
    return true;
  if (rhs.value < lhs.value)
    return false;
  if (lhs.start_time < rhs.start_time)
    return true;
  if (rhs.start_time < lhs.start_time)
    return false;
  if (lhs.timing_function < rhs.timing_function)
    return true;
  if (rhs.timing_function < lhs.timing_function)
    return false;
  return false;
}
template <typename StructPtrType>
AnimationKeyframeModelPtr AnimationKeyframeModel::Clone() const {
  return New(
      mojo::Clone(id),
      mojo::Clone(group_id),
      mojo::Clone(target_property_type),
      mojo::Clone(element_id),
      mojo::Clone(timing_function),
      mojo::Clone(keyframes),
      mojo::Clone(scaled_duration),
      mojo::Clone(direction),
      mojo::Clone(fill_mode),
      mojo::Clone(playback_rate),
      mojo::Clone(iterations),
      mojo::Clone(iteration_start),
      mojo::Clone(start_delay),
      mojo::Clone(hold_time)
  );
}

template <typename T, AnimationKeyframeModel::EnableIfSame<T>*>
bool AnimationKeyframeModel::Equals(const T& other_struct) const {
  if (!mojo::Equals(this->id, other_struct.id))
    return false;
  if (!mojo::Equals(this->group_id, other_struct.group_id))
    return false;
  if (!mojo::Equals(this->target_property_type, other_struct.target_property_type))
    return false;
  if (!mojo::Equals(this->element_id, other_struct.element_id))
    return false;
  if (!mojo::Equals(this->timing_function, other_struct.timing_function))
    return false;
  if (!mojo::Equals(this->keyframes, other_struct.keyframes))
    return false;
  if (!mojo::Equals(this->scaled_duration, other_struct.scaled_duration))
    return false;
  if (!mojo::Equals(this->direction, other_struct.direction))
    return false;
  if (!mojo::Equals(this->fill_mode, other_struct.fill_mode))
    return false;
  if (!mojo::Equals(this->playback_rate, other_struct.playback_rate))
    return false;
  if (!mojo::Equals(this->iterations, other_struct.iterations))
    return false;
  if (!mojo::Equals(this->iteration_start, other_struct.iteration_start))
    return false;
  if (!mojo::Equals(this->start_delay, other_struct.start_delay))
    return false;
  if (!mojo::Equals(this->hold_time, other_struct.hold_time))
    return false;
  return true;
}

template <typename T, AnimationKeyframeModel::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.id < rhs.id)
    return true;
  if (rhs.id < lhs.id)
    return false;
  if (lhs.group_id < rhs.group_id)
    return true;
  if (rhs.group_id < lhs.group_id)
    return false;
  if (lhs.target_property_type < rhs.target_property_type)
    return true;
  if (rhs.target_property_type < lhs.target_property_type)
    return false;
  if (lhs.element_id < rhs.element_id)
    return true;
  if (rhs.element_id < lhs.element_id)
    return false;
  if (lhs.timing_function < rhs.timing_function)
    return true;
  if (rhs.timing_function < lhs.timing_function)
    return false;
  if (lhs.keyframes < rhs.keyframes)
    return true;
  if (rhs.keyframes < lhs.keyframes)
    return false;
  if (lhs.scaled_duration < rhs.scaled_duration)
    return true;
  if (rhs.scaled_duration < lhs.scaled_duration)
    return false;
  if (lhs.direction < rhs.direction)
    return true;
  if (rhs.direction < lhs.direction)
    return false;
  if (lhs.fill_mode < rhs.fill_mode)
    return true;
  if (rhs.fill_mode < lhs.fill_mode)
    return false;
  if (lhs.playback_rate < rhs.playback_rate)
    return true;
  if (rhs.playback_rate < lhs.playback_rate)
    return false;
  if (lhs.iterations < rhs.iterations)
    return true;
  if (rhs.iterations < lhs.iterations)
    return false;
  if (lhs.iteration_start < rhs.iteration_start)
    return true;
  if (rhs.iteration_start < lhs.iteration_start)
    return false;
  if (lhs.start_delay < rhs.start_delay)
    return true;
  if (rhs.start_delay < lhs.start_delay)
    return false;
  if (lhs.hold_time < rhs.hold_time)
    return true;
  if (rhs.hold_time < lhs.hold_time)
    return false;
  return false;
}
template <typename StructPtrType>
AnimationPtr Animation::Clone() const {
  return New(
      mojo::Clone(id),
      mojo::Clone(element_id),
      mojo::Clone(keyframe_models)
  );
}

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

template <typename T, Animation::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.id < rhs.id)
    return true;
  if (rhs.id < lhs.id)
    return false;
  if (lhs.element_id < rhs.element_id)
    return true;
  if (rhs.element_id < lhs.element_id)
    return false;
  if (lhs.keyframe_models < rhs.keyframe_models)
    return true;
  if (rhs.keyframe_models < lhs.keyframe_models)
    return false;
  return false;
}
template <typename StructPtrType>
AnimationTimelinePtr AnimationTimeline::Clone() const {
  return New(
      mojo::Clone(id),
      mojo::Clone(new_animations),
      mojo::Clone(removed_animations)
  );
}

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

template <typename T, AnimationTimeline::EnableIfSame<T>*>
bool operator<(const T& lhs, const T& rhs) {
  if (lhs.id < rhs.id)
    return true;
  if (rhs.id < lhs.id)
    return false;
  if (lhs.new_animations < rhs.new_animations)
    return true;
  if (rhs.new_animations < lhs.new_animations)
    return false;
  if (lhs.removed_animations < rhs.removed_animations)
    return true;
  if (rhs.removed_animations < lhs.removed_animations)
    return false;
  return false;
}


}  // viz::mojom

namespace mojo {


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

  static decltype(::viz::mojom::CubicBezierTimingFunction::x1) x1(
      const ::viz::mojom::CubicBezierTimingFunctionPtr& input) {
    return input->x1;
  }

  static decltype(::viz::mojom::CubicBezierTimingFunction::y1) y1(
      const ::viz::mojom::CubicBezierTimingFunctionPtr& input) {
    return input->y1;
  }

  static decltype(::viz::mojom::CubicBezierTimingFunction::x2) x2(
      const ::viz::mojom::CubicBezierTimingFunctionPtr& input) {
    return input->x2;
  }

  static decltype(::viz::mojom::CubicBezierTimingFunction::y2) y2(
      const ::viz::mojom::CubicBezierTimingFunctionPtr& input) {
    return input->y2;
  }

  static bool Read(::viz::mojom::CubicBezierTimingFunction::DataView input, ::viz::mojom::CubicBezierTimingFunctionPtr* output);
};


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

  static decltype(::viz::mojom::StepsTimingFunction::num_steps) num_steps(
      const ::viz::mojom::StepsTimingFunctionPtr& input) {
    return input->num_steps;
  }

  static decltype(::viz::mojom::StepsTimingFunction::step_position) step_position(
      const ::viz::mojom::StepsTimingFunctionPtr& input) {
    return input->step_position;
  }

  static bool Read(::viz::mojom::StepsTimingFunction::DataView input, ::viz::mojom::StepsTimingFunctionPtr* output);
};


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

  static decltype(::viz::mojom::LinearEasingPoint::in) in(
      const ::viz::mojom::LinearEasingPointPtr& input) {
    return input->in;
  }

  static decltype(::viz::mojom::LinearEasingPoint::out) out(
      const ::viz::mojom::LinearEasingPointPtr& input) {
    return input->out;
  }

  static bool Read(::viz::mojom::LinearEasingPoint::DataView input, ::viz::mojom::LinearEasingPointPtr* output);
};


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

  static const decltype(::viz::mojom::AxisAngle::axis)& axis(
      const ::viz::mojom::AxisAnglePtr& input) {
    return input->axis;
  }

  static decltype(::viz::mojom::AxisAngle::angle) angle(
      const ::viz::mojom::AxisAnglePtr& input) {
    return input->angle;
  }

  static bool Read(::viz::mojom::AxisAngle::DataView input, ::viz::mojom::AxisAnglePtr* output);
};


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

  static const decltype(::viz::mojom::AnimationKeyframe::value)& value(
      const ::viz::mojom::AnimationKeyframePtr& input) {
    return input->value;
  }

  static const decltype(::viz::mojom::AnimationKeyframe::start_time)& start_time(
      const ::viz::mojom::AnimationKeyframePtr& input) {
    return input->start_time;
  }

  static const decltype(::viz::mojom::AnimationKeyframe::timing_function)& timing_function(
      const ::viz::mojom::AnimationKeyframePtr& input) {
    return input->timing_function;
  }

  static bool Read(::viz::mojom::AnimationKeyframe::DataView input, ::viz::mojom::AnimationKeyframePtr* output);
};


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

  static decltype(::viz::mojom::AnimationKeyframeModel::id) id(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->id;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::group_id) group_id(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->group_id;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::target_property_type) target_property_type(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->target_property_type;
  }

  static const decltype(::viz::mojom::AnimationKeyframeModel::element_id)& element_id(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->element_id;
  }

  static const decltype(::viz::mojom::AnimationKeyframeModel::timing_function)& timing_function(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->timing_function;
  }

  static const decltype(::viz::mojom::AnimationKeyframeModel::keyframes)& keyframes(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->keyframes;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::scaled_duration) scaled_duration(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->scaled_duration;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::direction) direction(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->direction;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::fill_mode) fill_mode(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->fill_mode;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::playback_rate) playback_rate(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->playback_rate;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::iterations) iterations(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->iterations;
  }

  static decltype(::viz::mojom::AnimationKeyframeModel::iteration_start) iteration_start(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->iteration_start;
  }

  static const decltype(::viz::mojom::AnimationKeyframeModel::start_delay)& start_delay(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->start_delay;
  }

  static const decltype(::viz::mojom::AnimationKeyframeModel::hold_time)& hold_time(
      const ::viz::mojom::AnimationKeyframeModelPtr& input) {
    return input->hold_time;
  }

  static bool Read(::viz::mojom::AnimationKeyframeModel::DataView input, ::viz::mojom::AnimationKeyframeModelPtr* output);
};


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

  static decltype(::viz::mojom::Animation::id) id(
      const ::viz::mojom::AnimationPtr& input) {
    return input->id;
  }

  static const decltype(::viz::mojom::Animation::element_id)& element_id(
      const ::viz::mojom::AnimationPtr& input) {
    return input->element_id;
  }

  static const decltype(::viz::mojom::Animation::keyframe_models)& keyframe_models(
      const ::viz::mojom::AnimationPtr& input) {
    return input->keyframe_models;
  }

  static bool Read(::viz::mojom::Animation::DataView input, ::viz::mojom::AnimationPtr* output);
};


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

  static decltype(::viz::mojom::AnimationTimeline::id) id(
      const ::viz::mojom::AnimationTimelinePtr& input) {
    return input->id;
  }

  static const decltype(::viz::mojom::AnimationTimeline::new_animations)& new_animations(
      const ::viz::mojom::AnimationTimelinePtr& input) {
    return input->new_animations;
  }

  static const decltype(::viz::mojom::AnimationTimeline::removed_animations)& removed_animations(
      const ::viz::mojom::AnimationTimelinePtr& input) {
    return input->removed_animations;
  }

  static bool Read(::viz::mojom::AnimationTimeline::DataView input, ::viz::mojom::AnimationTimelinePtr* output);
};


template <>
struct  UnionTraits<::viz::mojom::TimingFunction::DataView,
                                        ::viz::mojom::TimingFunctionPtr> {
  static bool IsNull(const ::viz::mojom::TimingFunctionPtr& input) { return !input; }
  static void SetToNull(::viz::mojom::TimingFunctionPtr* output) { output->reset(); }

  static ::viz::mojom::TimingFunction::Tag GetTag(const ::viz::mojom::TimingFunctionPtr& input) {
    return input->which();
  }

  static const ::viz::mojom::CubicBezierTimingFunctionPtr& cubic_bezier(const ::viz::mojom::TimingFunctionPtr& input) {
    return input->get_cubic_bezier();
  }

  static const ::viz::mojom::StepsTimingFunctionPtr& steps(const ::viz::mojom::TimingFunctionPtr& input) {
    return input->get_steps();
  }

  static const std::vector<::viz::mojom::LinearEasingPointPtr>& linear(const ::viz::mojom::TimingFunctionPtr& input) {
    return input->get_linear();
  }

  static bool Read(::viz::mojom::TimingFunction::DataView input, ::viz::mojom::TimingFunctionPtr* output);
};


template <>
struct  UnionTraits<::viz::mojom::TransformOperation::DataView,
                                        ::viz::mojom::TransformOperationPtr> {
  static bool IsNull(const ::viz::mojom::TransformOperationPtr& input) { return !input; }
  static void SetToNull(::viz::mojom::TransformOperationPtr* output) { output->reset(); }

  static ::viz::mojom::TransformOperation::Tag GetTag(const ::viz::mojom::TransformOperationPtr& input) {
    return input->which();
  }

  static  bool identity(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_identity();
  }

  static  float perspective_depth(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_perspective_depth();
  }

  static const ::gfx::Vector2dF& skew(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_skew();
  }

  static const ::gfx::Vector3dF& scale(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_scale();
  }

  static const ::gfx::Vector3dF& translate(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_translate();
  }

  static const ::viz::mojom::AxisAnglePtr& rotate(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_rotate();
  }

  static const ::gfx::Transform& matrix(const ::viz::mojom::TransformOperationPtr& input) {
    return input->get_matrix();
  }

  static bool Read(::viz::mojom::TransformOperation::DataView input, ::viz::mojom::TransformOperationPtr* output);
};


template <>
struct  UnionTraits<::viz::mojom::AnimationKeyframeValue::DataView,
                                        ::viz::mojom::AnimationKeyframeValuePtr> {
  static bool IsNull(const ::viz::mojom::AnimationKeyframeValuePtr& input) { return !input; }
  static void SetToNull(::viz::mojom::AnimationKeyframeValuePtr* output) { output->reset(); }

  static ::viz::mojom::AnimationKeyframeValue::Tag GetTag(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->which();
  }

  static  float scalar(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->get_scalar();
  }

  static const ::SkColor& color(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->get_color();
  }

  static const ::gfx::SizeF& size(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->get_size();
  }

  static const ::gfx::Rect& rect(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->get_rect();
  }

  static const std::vector<::viz::mojom::TransformOperationPtr>& transform(const ::viz::mojom::AnimationKeyframeValuePtr& input) {
    return input->get_transform();
  }

  static bool Read(::viz::mojom::AnimationKeyframeValue::DataView input, ::viz::mojom::AnimationKeyframeValuePtr* output);
};

}  // namespace mojo

#endif  // SERVICES_VIZ_PUBLIC_MOJOM_COMPOSITING_ANIMATION_MOJOM_H_