/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*******************************************************************************
 * AUTOGENERATED - DO NOT EDIT
 *******************************************************************************
 * This file has been generated from the protobuf message
 * perfetto/config/trace_config.proto
 * by
 * ../../tools/proto_to_cpp/proto_to_cpp.cc.
 * If you need to make changes here, change the .proto file and then run
 * ./tools/gen_tracing_cpp_headers_from_protos.py
 */

#include "perfetto/tracing/core/trace_config.h"

#include "perfetto/config/data_source_config.pb.h"
#include "perfetto/config/trace_config.pb.h"

namespace perfetto {

TraceConfig::TraceConfig() = default;
TraceConfig::~TraceConfig() = default;
TraceConfig::TraceConfig(const TraceConfig&) = default;
TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;

void TraceConfig::FromProto(const perfetto::protos::TraceConfig& proto) {
  buffers_.clear();
  for (const auto& field : proto.buffers()) {
    buffers_.emplace_back();
    buffers_.back().FromProto(field);
  }

  data_sources_.clear();
  for (const auto& field : proto.data_sources()) {
    data_sources_.emplace_back();
    data_sources_.back().FromProto(field);
  }

  static_assert(sizeof(duration_ms_) == sizeof(proto.duration_ms()),
                "size mismatch");
  duration_ms_ = static_cast<decltype(duration_ms_)>(proto.duration_ms());

  static_assert(sizeof(enable_extra_guardrails_) ==
                    sizeof(proto.enable_extra_guardrails()),
                "size mismatch");
  enable_extra_guardrails_ = static_cast<decltype(enable_extra_guardrails_)>(
      proto.enable_extra_guardrails());

  static_assert(sizeof(lockdown_mode_) == sizeof(proto.lockdown_mode()),
                "size mismatch");
  lockdown_mode_ = static_cast<decltype(lockdown_mode_)>(proto.lockdown_mode());

  producers_.clear();
  for (const auto& field : proto.producers()) {
    producers_.emplace_back();
    producers_.back().FromProto(field);
  }

  statsd_metadata_.FromProto(proto.statsd_metadata());

  static_assert(sizeof(write_into_file_) == sizeof(proto.write_into_file()),
                "size mismatch");
  write_into_file_ =
      static_cast<decltype(write_into_file_)>(proto.write_into_file());

  static_assert(
      sizeof(file_write_period_ms_) == sizeof(proto.file_write_period_ms()),
      "size mismatch");
  file_write_period_ms_ = static_cast<decltype(file_write_period_ms_)>(
      proto.file_write_period_ms());

  static_assert(
      sizeof(max_file_size_bytes_) == sizeof(proto.max_file_size_bytes()),
      "size mismatch");
  max_file_size_bytes_ =
      static_cast<decltype(max_file_size_bytes_)>(proto.max_file_size_bytes());
  unknown_fields_ = proto.unknown_fields();
}

void TraceConfig::ToProto(perfetto::protos::TraceConfig* proto) const {
  proto->Clear();

  for (const auto& it : buffers_) {
    auto* entry = proto->add_buffers();
    it.ToProto(entry);
  }

  for (const auto& it : data_sources_) {
    auto* entry = proto->add_data_sources();
    it.ToProto(entry);
  }

  static_assert(sizeof(duration_ms_) == sizeof(proto->duration_ms()),
                "size mismatch");
  proto->set_duration_ms(
      static_cast<decltype(proto->duration_ms())>(duration_ms_));

  static_assert(sizeof(enable_extra_guardrails_) ==
                    sizeof(proto->enable_extra_guardrails()),
                "size mismatch");
  proto->set_enable_extra_guardrails(
      static_cast<decltype(proto->enable_extra_guardrails())>(
          enable_extra_guardrails_));

  static_assert(sizeof(lockdown_mode_) == sizeof(proto->lockdown_mode()),
                "size mismatch");
  proto->set_lockdown_mode(
      static_cast<decltype(proto->lockdown_mode())>(lockdown_mode_));

  for (const auto& it : producers_) {
    auto* entry = proto->add_producers();
    it.ToProto(entry);
  }

  statsd_metadata_.ToProto(proto->mutable_statsd_metadata());

  static_assert(sizeof(write_into_file_) == sizeof(proto->write_into_file()),
                "size mismatch");
  proto->set_write_into_file(
      static_cast<decltype(proto->write_into_file())>(write_into_file_));

  static_assert(
      sizeof(file_write_period_ms_) == sizeof(proto->file_write_period_ms()),
      "size mismatch");
  proto->set_file_write_period_ms(
      static_cast<decltype(proto->file_write_period_ms())>(
          file_write_period_ms_));

  static_assert(
      sizeof(max_file_size_bytes_) == sizeof(proto->max_file_size_bytes()),
      "size mismatch");
  proto->set_max_file_size_bytes(
      static_cast<decltype(proto->max_file_size_bytes())>(
          max_file_size_bytes_));
  *(proto->mutable_unknown_fields()) = unknown_fields_;
}

TraceConfig::BufferConfig::BufferConfig() = default;
TraceConfig::BufferConfig::~BufferConfig() = default;
TraceConfig::BufferConfig::BufferConfig(const TraceConfig::BufferConfig&) =
    default;
TraceConfig::BufferConfig& TraceConfig::BufferConfig::operator=(
    const TraceConfig::BufferConfig&) = default;
TraceConfig::BufferConfig::BufferConfig(TraceConfig::BufferConfig&&) noexcept =
    default;
TraceConfig::BufferConfig& TraceConfig::BufferConfig::operator=(
    TraceConfig::BufferConfig&&) = default;

void TraceConfig::BufferConfig::FromProto(
    const perfetto::protos::TraceConfig_BufferConfig& proto) {
  static_assert(sizeof(size_kb_) == sizeof(proto.size_kb()), "size mismatch");
  size_kb_ = static_cast<decltype(size_kb_)>(proto.size_kb());

  static_assert(sizeof(fill_policy_) == sizeof(proto.fill_policy()),
                "size mismatch");
  fill_policy_ = static_cast<decltype(fill_policy_)>(proto.fill_policy());
  unknown_fields_ = proto.unknown_fields();
}

void TraceConfig::BufferConfig::ToProto(
    perfetto::protos::TraceConfig_BufferConfig* proto) const {
  proto->Clear();

  static_assert(sizeof(size_kb_) == sizeof(proto->size_kb()), "size mismatch");
  proto->set_size_kb(static_cast<decltype(proto->size_kb())>(size_kb_));

  static_assert(sizeof(fill_policy_) == sizeof(proto->fill_policy()),
                "size mismatch");
  proto->set_fill_policy(
      static_cast<decltype(proto->fill_policy())>(fill_policy_));
  *(proto->mutable_unknown_fields()) = unknown_fields_;
}

TraceConfig::DataSource::DataSource() = default;
TraceConfig::DataSource::~DataSource() = default;
TraceConfig::DataSource::DataSource(const TraceConfig::DataSource&) = default;
TraceConfig::DataSource& TraceConfig::DataSource::operator=(
    const TraceConfig::DataSource&) = default;
TraceConfig::DataSource::DataSource(TraceConfig::DataSource&&) noexcept =
    default;
TraceConfig::DataSource& TraceConfig::DataSource::operator=(
    TraceConfig::DataSource&&) = default;

void TraceConfig::DataSource::FromProto(
    const perfetto::protos::TraceConfig_DataSource& proto) {
  config_.FromProto(proto.config());

  producer_name_filter_.clear();
  for (const auto& field : proto.producer_name_filter()) {
    producer_name_filter_.emplace_back();
    static_assert(sizeof(producer_name_filter_.back()) ==
                      sizeof(proto.producer_name_filter(0)),
                  "size mismatch");
    producer_name_filter_.back() =
        static_cast<decltype(producer_name_filter_)::value_type>(field);
  }
  unknown_fields_ = proto.unknown_fields();
}

void TraceConfig::DataSource::ToProto(
    perfetto::protos::TraceConfig_DataSource* proto) const {
  proto->Clear();

  config_.ToProto(proto->mutable_config());

  for (const auto& it : producer_name_filter_) {
    proto->add_producer_name_filter(
        static_cast<decltype(proto->producer_name_filter(0))>(it));
    static_assert(sizeof(it) == sizeof(proto->producer_name_filter(0)),
                  "size mismatch");
  }
  *(proto->mutable_unknown_fields()) = unknown_fields_;
}

TraceConfig::ProducerConfig::ProducerConfig() = default;
TraceConfig::ProducerConfig::~ProducerConfig() = default;
TraceConfig::ProducerConfig::ProducerConfig(
    const TraceConfig::ProducerConfig&) = default;
TraceConfig::ProducerConfig& TraceConfig::ProducerConfig::operator=(
    const TraceConfig::ProducerConfig&) = default;
TraceConfig::ProducerConfig::ProducerConfig(
    TraceConfig::ProducerConfig&&) noexcept = default;
TraceConfig::ProducerConfig& TraceConfig::ProducerConfig::operator=(
    TraceConfig::ProducerConfig&&) = default;

void TraceConfig::ProducerConfig::FromProto(
    const perfetto::protos::TraceConfig_ProducerConfig& proto) {
  static_assert(sizeof(producer_name_) == sizeof(proto.producer_name()),
                "size mismatch");
  producer_name_ = static_cast<decltype(producer_name_)>(proto.producer_name());

  static_assert(sizeof(shm_size_kb_) == sizeof(proto.shm_size_kb()),
                "size mismatch");
  shm_size_kb_ = static_cast<decltype(shm_size_kb_)>(proto.shm_size_kb());

  static_assert(sizeof(page_size_kb_) == sizeof(proto.page_size_kb()),
                "size mismatch");
  page_size_kb_ = static_cast<decltype(page_size_kb_)>(proto.page_size_kb());
  unknown_fields_ = proto.unknown_fields();
}

void TraceConfig::ProducerConfig::ToProto(
    perfetto::protos::TraceConfig_ProducerConfig* proto) const {
  proto->Clear();

  static_assert(sizeof(producer_name_) == sizeof(proto->producer_name()),
                "size mismatch");
  proto->set_producer_name(
      static_cast<decltype(proto->producer_name())>(producer_name_));

  static_assert(sizeof(shm_size_kb_) == sizeof(proto->shm_size_kb()),
                "size mismatch");
  proto->set_shm_size_kb(
      static_cast<decltype(proto->shm_size_kb())>(shm_size_kb_));

  static_assert(sizeof(page_size_kb_) == sizeof(proto->page_size_kb()),
                "size mismatch");
  proto->set_page_size_kb(
      static_cast<decltype(proto->page_size_kb())>(page_size_kb_));
  *(proto->mutable_unknown_fields()) = unknown_fields_;
}

TraceConfig::StatsdMetadata::StatsdMetadata() = default;
TraceConfig::StatsdMetadata::~StatsdMetadata() = default;
TraceConfig::StatsdMetadata::StatsdMetadata(
    const TraceConfig::StatsdMetadata&) = default;
TraceConfig::StatsdMetadata& TraceConfig::StatsdMetadata::operator=(
    const TraceConfig::StatsdMetadata&) = default;
TraceConfig::StatsdMetadata::StatsdMetadata(
    TraceConfig::StatsdMetadata&&) noexcept = default;
TraceConfig::StatsdMetadata& TraceConfig::StatsdMetadata::operator=(
    TraceConfig::StatsdMetadata&&) = default;

void TraceConfig::StatsdMetadata::FromProto(
    const perfetto::protos::TraceConfig_StatsdMetadata& proto) {
  static_assert(
      sizeof(triggering_alert_id_) == sizeof(proto.triggering_alert_id()),
      "size mismatch");
  triggering_alert_id_ =
      static_cast<decltype(triggering_alert_id_)>(proto.triggering_alert_id());

  static_assert(
      sizeof(triggering_config_uid_) == sizeof(proto.triggering_config_uid()),
      "size mismatch");
  triggering_config_uid_ = static_cast<decltype(triggering_config_uid_)>(
      proto.triggering_config_uid());

  static_assert(
      sizeof(triggering_config_id_) == sizeof(proto.triggering_config_id()),
      "size mismatch");
  triggering_config_id_ = static_cast<decltype(triggering_config_id_)>(
      proto.triggering_config_id());
  unknown_fields_ = proto.unknown_fields();
}

void TraceConfig::StatsdMetadata::ToProto(
    perfetto::protos::TraceConfig_StatsdMetadata* proto) const {
  proto->Clear();

  static_assert(
      sizeof(triggering_alert_id_) == sizeof(proto->triggering_alert_id()),
      "size mismatch");
  proto->set_triggering_alert_id(
      static_cast<decltype(proto->triggering_alert_id())>(
          triggering_alert_id_));

  static_assert(
      sizeof(triggering_config_uid_) == sizeof(proto->triggering_config_uid()),
      "size mismatch");
  proto->set_triggering_config_uid(
      static_cast<decltype(proto->triggering_config_uid())>(
          triggering_config_uid_));

  static_assert(
      sizeof(triggering_config_id_) == sizeof(proto->triggering_config_id()),
      "size mismatch");
  proto->set_triggering_config_id(
      static_cast<decltype(proto->triggering_config_id())>(
          triggering_config_id_));
  *(proto->mutable_unknown_fields()) = unknown_fields_;
}

}  // namespace perfetto
