// Copyright 2016 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 CHROME_BROWSER_UI_WEBUI_DISCARDS_DISCARDS_MOJOM_SHARED_INTERNAL_H_
#define CHROME_BROWSER_UI_WEBUI_DISCARDS_DISCARDS_MOJOM_SHARED_INTERNAL_H_

#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
#include "mojo/public/cpp/bindings/lib/buffer.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit_state.mojom-shared-internal.h"
#include "mojo/public/cpp/bindings/lib/native_enum_data.h"
#include "mojo/public/interfaces/bindings/native_struct.mojom-shared-internal.h"

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

namespace mojo {
namespace internal {
class ValidationContext;
}
}
namespace mojom {
namespace internal {
class SiteCharacteristicsFeature_Data;
class SiteCharacteristicsPerformanceMeasurement_Data;
class SiteCharacteristicsDatabaseSize_Data;
class SiteCharacteristicsDatabaseValue_Data;
class SiteCharacteristicsDatabaseEntry_Data;
class SiteCharacteristicsDatabase_Data;
class TabDiscardsInfo_Data;

struct LifecycleUnitVisibility_Data {
 public:
  static bool constexpr kIsExtensible = false;

  static bool IsKnownValue(int32_t value) {
    switch (value) {
      case 0:
      case 1:
      case 2:
        return true;
    }
    return false;
  }

  static bool Validate(int32_t value,
                       mojo::internal::ValidationContext* validation_context) {
    if (kIsExtensible || IsKnownValue(value))
      return true;

    ReportValidationError(validation_context,
                          mojo::internal::VALIDATION_ERROR_UNKNOWN_ENUM_VALUE);
    return false;
  }
};

#pragma pack(push, 1)
class  SiteCharacteristicsFeature_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsFeature_Data));
      new (data()) SiteCharacteristicsFeature_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsFeature_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsFeature_Data>(index_);
    }
    SiteCharacteristicsFeature_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  int64_t observation_duration;
  int64_t use_timestamp;

 private:
  SiteCharacteristicsFeature_Data();
  ~SiteCharacteristicsFeature_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsFeature_Data) == 24,
              "Bad sizeof(SiteCharacteristicsFeature_Data)");
// Used by SiteCharacteristicsFeature::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsFeature_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsFeature_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsFeature_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsFeature_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsFeature_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  SiteCharacteristicsPerformanceMeasurement_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsPerformanceMeasurement_Data));
      new (data()) SiteCharacteristicsPerformanceMeasurement_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsPerformanceMeasurement_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsPerformanceMeasurement_Data>(index_);
    }
    SiteCharacteristicsPerformanceMeasurement_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  float avg_cpu_usage_us;
  float avg_footprint_kb;
  float avg_load_duration_us;
  uint8_t padfinal_[4];

 private:
  SiteCharacteristicsPerformanceMeasurement_Data();
  ~SiteCharacteristicsPerformanceMeasurement_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsPerformanceMeasurement_Data) == 24,
              "Bad sizeof(SiteCharacteristicsPerformanceMeasurement_Data)");
// Used by SiteCharacteristicsPerformanceMeasurement::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsPerformanceMeasurement_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsPerformanceMeasurement_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsPerformanceMeasurement_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsPerformanceMeasurement_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsPerformanceMeasurement_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  SiteCharacteristicsDatabaseSize_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsDatabaseSize_Data));
      new (data()) SiteCharacteristicsDatabaseSize_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsDatabaseSize_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsDatabaseSize_Data>(index_);
    }
    SiteCharacteristicsDatabaseSize_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  int64_t num_rows;
  int64_t on_disk_size_kb;

 private:
  SiteCharacteristicsDatabaseSize_Data();
  ~SiteCharacteristicsDatabaseSize_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsDatabaseSize_Data) == 24,
              "Bad sizeof(SiteCharacteristicsDatabaseSize_Data)");
// Used by SiteCharacteristicsDatabaseSize::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsDatabaseSize_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsDatabaseSize_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsDatabaseSize_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsDatabaseSize_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsDatabaseSize_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  SiteCharacteristicsDatabaseValue_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsDatabaseValue_Data));
      new (data()) SiteCharacteristicsDatabaseValue_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsDatabaseValue_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsDatabaseValue_Data>(index_);
    }
    SiteCharacteristicsDatabaseValue_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  uint32_t last_loaded;
  uint8_t pad0_[4];
  mojo::internal::Pointer<internal::SiteCharacteristicsFeature_Data> updates_favicon_in_background;
  mojo::internal::Pointer<internal::SiteCharacteristicsFeature_Data> updates_title_in_background;
  mojo::internal::Pointer<internal::SiteCharacteristicsFeature_Data> uses_audio_in_background;
  mojo::internal::Pointer<internal::SiteCharacteristicsFeature_Data> uses_notifications_in_background;
  mojo::internal::Pointer<internal::SiteCharacteristicsPerformanceMeasurement_Data> load_time_estimates;

 private:
  SiteCharacteristicsDatabaseValue_Data();
  ~SiteCharacteristicsDatabaseValue_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsDatabaseValue_Data) == 56,
              "Bad sizeof(SiteCharacteristicsDatabaseValue_Data)");
// Used by SiteCharacteristicsDatabaseValue::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsDatabaseValue_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsDatabaseValue_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsDatabaseValue_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsDatabaseValue_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsDatabaseValue_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  SiteCharacteristicsDatabaseEntry_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsDatabaseEntry_Data));
      new (data()) SiteCharacteristicsDatabaseEntry_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsDatabaseEntry_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsDatabaseEntry_Data>(index_);
    }
    SiteCharacteristicsDatabaseEntry_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  mojo::internal::Pointer<mojo::internal::String_Data> origin;
  uint8_t is_dirty : 1;
  uint8_t pad1_[7];
  mojo::internal::Pointer<internal::SiteCharacteristicsDatabaseValue_Data> value;

 private:
  SiteCharacteristicsDatabaseEntry_Data();
  ~SiteCharacteristicsDatabaseEntry_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsDatabaseEntry_Data) == 32,
              "Bad sizeof(SiteCharacteristicsDatabaseEntry_Data)");
// Used by SiteCharacteristicsDatabaseEntry::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsDatabaseEntry_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsDatabaseEntry_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsDatabaseEntry_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsDatabaseEntry_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsDatabaseEntry_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  SiteCharacteristicsDatabase_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(SiteCharacteristicsDatabase_Data));
      new (data()) SiteCharacteristicsDatabase_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    SiteCharacteristicsDatabase_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<SiteCharacteristicsDatabase_Data>(index_);
    }
    SiteCharacteristicsDatabase_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  mojo::internal::Pointer<mojo::internal::Array_Data<mojo::internal::Pointer<internal::SiteCharacteristicsDatabaseEntry_Data>>> db_rows;

 private:
  SiteCharacteristicsDatabase_Data();
  ~SiteCharacteristicsDatabase_Data() = delete;
};
static_assert(sizeof(SiteCharacteristicsDatabase_Data) == 16,
              "Bad sizeof(SiteCharacteristicsDatabase_Data)");
// Used by SiteCharacteristicsDatabase::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct SiteCharacteristicsDatabase_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  SiteCharacteristicsDatabase_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~SiteCharacteristicsDatabase_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    SiteCharacteristicsDatabase_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    SiteCharacteristicsDatabase_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
class  TabDiscardsInfo_Data {
 public:
  class BufferWriter {
   public:
    BufferWriter() = default;

    void Allocate(mojo::internal::Buffer* serialization_buffer) {
      serialization_buffer_ = serialization_buffer;
      index_ = serialization_buffer_->Allocate(sizeof(TabDiscardsInfo_Data));
      new (data()) TabDiscardsInfo_Data();
    }

    bool is_null() const { return !serialization_buffer_; }
    TabDiscardsInfo_Data* data() {
      DCHECK(!is_null());
      return serialization_buffer_->Get<TabDiscardsInfo_Data>(index_);
    }
    TabDiscardsInfo_Data* operator->() { return data(); }

   private:
    mojo::internal::Buffer* serialization_buffer_ = nullptr;
    size_t index_ = 0;

    DISALLOW_COPY_AND_ASSIGN(BufferWriter);
  };

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

  mojo::internal::StructHeader header_;
  mojo::internal::Pointer<mojo::internal::String_Data> tab_url;
  mojo::internal::Pointer<mojo::internal::String_Data> title;
  int32_t visibility;
  int32_t loading_state;
  int32_t state;
  uint8_t can_freeze : 1;
  uint8_t can_discard : 1;
  uint8_t is_auto_discardable : 1;
  uint8_t has_reactivation_score : 1;
  uint8_t has_focus : 1;
  uint8_t pad9_[3];
  mojo::internal::Pointer<mojo::internal::Array_Data<mojo::internal::Pointer<mojo::internal::String_Data>>> cannot_freeze_reasons;
  mojo::internal::Pointer<mojo::internal::Array_Data<mojo::internal::Pointer<mojo::internal::String_Data>>> cannot_discard_reasons;
  int32_t discard_count;
  int32_t discard_reason;
  int32_t utility_rank;
  int32_t last_active_seconds;
  int32_t id;
  uint8_t pad16_[4];
  double reactivation_score;
  double site_engagement_score;

 private:
  TabDiscardsInfo_Data();
  ~TabDiscardsInfo_Data() = delete;
};
static_assert(sizeof(TabDiscardsInfo_Data) == 96,
              "Bad sizeof(TabDiscardsInfo_Data)");
// Used by TabDiscardsInfo::WrapAsMessage to lazily serialize the struct.
template <typename UserType, typename DataView>
struct TabDiscardsInfo_UnserializedMessageContext
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  TabDiscardsInfo_UnserializedMessageContext(
    uint32_t message_name,
    uint32_t message_flags,
    UserType input)
      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
      , user_data_(std::move(input)) {}
  ~TabDiscardsInfo_UnserializedMessageContext() override = default;

  UserType TakeData() {
    return std::move(user_data_);
  }

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* context,
                 mojo::internal::Buffer* buffer) override {
    TabDiscardsInfo_Data::BufferWriter writer;
    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
  }

  UserType user_data_;
};

template <typename UserType, typename DataView>
const mojo::internal::UnserializedMessageContext::Tag
    TabDiscardsInfo_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};

#pragma pack(pop)

}  // namespace internal
}  // namespace mojom

#endif  // CHROME_BROWSER_UI_WEBUI_DISCARDS_DISCARDS_MOJOM_SHARED_INTERNAL_H_
/* Metadata comment
eyJtZXRhIjogW10sICJ0eXBlIjogImt5dGhlMCJ9
*/