// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.

#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_

#include <stddef.h>
#include <stdint.h>

#include "perfetto/protozero/field_writer.h"
#include "perfetto/protozero/message.h"
#include "perfetto/protozero/packed_repeated_fields.h"
#include "perfetto/protozero/proto_decoder.h"
#include "perfetto/protozero/proto_utils.h"

namespace perfetto {
namespace protos {
namespace pbzero {

class DataSourceConfig;
class TraceConfig_BufferConfig;
class TraceConfig_BuiltinDataSource;
class TraceConfig_DataSource;
class TraceConfig_GuardrailOverrides;
class TraceConfig_IncidentReportConfig;
class TraceConfig_IncrementalStateConfig;
class TraceConfig_ProducerConfig;
class TraceConfig_StatsdMetadata;
class TraceConfig_TraceFilter;
class TraceConfig_TriggerConfig;
class TraceConfig_TriggerConfig_Trigger;
enum BuiltinClock : int32_t;
enum TraceConfig_BufferConfig_FillPolicy : int32_t;
enum TraceConfig_CompressionType : int32_t;
enum TraceConfig_LockdownModeOperation : int32_t;
enum TraceConfig_StatsdLogging : int32_t;
enum TraceConfig_TriggerConfig_TriggerMode : int32_t;

enum TraceConfig_LockdownModeOperation : int32_t {
  TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
  TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
  TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
};

const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;

enum TraceConfig_CompressionType : int32_t {
  TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
  TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
};

const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;

enum TraceConfig_StatsdLogging : int32_t {
  TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
  TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
  TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
};

const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;

enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
};

const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;

enum TraceConfig_BufferConfig_FillPolicy : int32_t {
  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
};

const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;

class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/33, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
 public:
  TraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_buffers() const { return at<1>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffers() const { return GetRepeated<::protozero::ConstBytes>(1); }
  bool has_data_sources() const { return at<2>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
  bool has_builtin_data_sources() const { return at<20>().valid(); }
  ::protozero::ConstBytes builtin_data_sources() const { return at<20>().as_bytes(); }
  bool has_duration_ms() const { return at<3>().valid(); }
  uint32_t duration_ms() const { return at<3>().as_uint32(); }
  bool has_enable_extra_guardrails() const { return at<4>().valid(); }
  bool enable_extra_guardrails() const { return at<4>().as_bool(); }
  bool has_lockdown_mode() const { return at<5>().valid(); }
  int32_t lockdown_mode() const { return at<5>().as_int32(); }
  bool has_producers() const { return at<6>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(6); }
  bool has_statsd_metadata() const { return at<7>().valid(); }
  ::protozero::ConstBytes statsd_metadata() const { return at<7>().as_bytes(); }
  bool has_write_into_file() const { return at<8>().valid(); }
  bool write_into_file() const { return at<8>().as_bool(); }
  bool has_output_path() const { return at<29>().valid(); }
  ::protozero::ConstChars output_path() const { return at<29>().as_string(); }
  bool has_file_write_period_ms() const { return at<9>().valid(); }
  uint32_t file_write_period_ms() const { return at<9>().as_uint32(); }
  bool has_max_file_size_bytes() const { return at<10>().valid(); }
  uint64_t max_file_size_bytes() const { return at<10>().as_uint64(); }
  bool has_guardrail_overrides() const { return at<11>().valid(); }
  ::protozero::ConstBytes guardrail_overrides() const { return at<11>().as_bytes(); }
  bool has_deferred_start() const { return at<12>().valid(); }
  bool deferred_start() const { return at<12>().as_bool(); }
  bool has_flush_period_ms() const { return at<13>().valid(); }
  uint32_t flush_period_ms() const { return at<13>().as_uint32(); }
  bool has_flush_timeout_ms() const { return at<14>().valid(); }
  uint32_t flush_timeout_ms() const { return at<14>().as_uint32(); }
  bool has_data_source_stop_timeout_ms() const { return at<23>().valid(); }
  uint32_t data_source_stop_timeout_ms() const { return at<23>().as_uint32(); }
  bool has_notify_traceur() const { return at<16>().valid(); }
  bool notify_traceur() const { return at<16>().as_bool(); }
  bool has_bugreport_score() const { return at<30>().valid(); }
  int32_t bugreport_score() const { return at<30>().as_int32(); }
  bool has_trigger_config() const { return at<17>().valid(); }
  ::protozero::ConstBytes trigger_config() const { return at<17>().as_bytes(); }
  bool has_activate_triggers() const { return at<18>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> activate_triggers() const { return GetRepeated<::protozero::ConstChars>(18); }
  bool has_incremental_state_config() const { return at<21>().valid(); }
  ::protozero::ConstBytes incremental_state_config() const { return at<21>().as_bytes(); }
  bool has_allow_user_build_tracing() const { return at<19>().valid(); }
  bool allow_user_build_tracing() const { return at<19>().as_bool(); }
  bool has_unique_session_name() const { return at<22>().valid(); }
  ::protozero::ConstChars unique_session_name() const { return at<22>().as_string(); }
  bool has_compression_type() const { return at<24>().valid(); }
  int32_t compression_type() const { return at<24>().as_int32(); }
  bool has_incident_report_config() const { return at<25>().valid(); }
  ::protozero::ConstBytes incident_report_config() const { return at<25>().as_bytes(); }
  bool has_statsd_logging() const { return at<31>().valid(); }
  int32_t statsd_logging() const { return at<31>().as_int32(); }
  bool has_trace_uuid_msb() const { return at<27>().valid(); }
  int64_t trace_uuid_msb() const { return at<27>().as_int64(); }
  bool has_trace_uuid_lsb() const { return at<28>().valid(); }
  int64_t trace_uuid_lsb() const { return at<28>().as_int64(); }
  bool has_trace_filter() const { return at<33>().valid(); }
  ::protozero::ConstBytes trace_filter() const { return at<33>().as_bytes(); }
};

class TraceConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_Decoder;
  enum : int32_t {
    kBuffersFieldNumber = 1,
    kDataSourcesFieldNumber = 2,
    kBuiltinDataSourcesFieldNumber = 20,
    kDurationMsFieldNumber = 3,
    kEnableExtraGuardrailsFieldNumber = 4,
    kLockdownModeFieldNumber = 5,
    kProducersFieldNumber = 6,
    kStatsdMetadataFieldNumber = 7,
    kWriteIntoFileFieldNumber = 8,
    kOutputPathFieldNumber = 29,
    kFileWritePeriodMsFieldNumber = 9,
    kMaxFileSizeBytesFieldNumber = 10,
    kGuardrailOverridesFieldNumber = 11,
    kDeferredStartFieldNumber = 12,
    kFlushPeriodMsFieldNumber = 13,
    kFlushTimeoutMsFieldNumber = 14,
    kDataSourceStopTimeoutMsFieldNumber = 23,
    kNotifyTraceurFieldNumber = 16,
    kBugreportScoreFieldNumber = 30,
    kTriggerConfigFieldNumber = 17,
    kActivateTriggersFieldNumber = 18,
    kIncrementalStateConfigFieldNumber = 21,
    kAllowUserBuildTracingFieldNumber = 19,
    kUniqueSessionNameFieldNumber = 22,
    kCompressionTypeFieldNumber = 24,
    kIncidentReportConfigFieldNumber = 25,
    kStatsdLoggingFieldNumber = 31,
    kTraceUuidMsbFieldNumber = 27,
    kTraceUuidLsbFieldNumber = 28,
    kTraceFilterFieldNumber = 33,
  };
  using BufferConfig = ::perfetto::protos::pbzero::TraceConfig_BufferConfig;
  using DataSource = ::perfetto::protos::pbzero::TraceConfig_DataSource;
  using BuiltinDataSource = ::perfetto::protos::pbzero::TraceConfig_BuiltinDataSource;
  using ProducerConfig = ::perfetto::protos::pbzero::TraceConfig_ProducerConfig;
  using StatsdMetadata = ::perfetto::protos::pbzero::TraceConfig_StatsdMetadata;
  using GuardrailOverrides = ::perfetto::protos::pbzero::TraceConfig_GuardrailOverrides;
  using TriggerConfig = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig;
  using IncrementalStateConfig = ::perfetto::protos::pbzero::TraceConfig_IncrementalStateConfig;
  using IncidentReportConfig = ::perfetto::protos::pbzero::TraceConfig_IncidentReportConfig;
  using TraceFilter = ::perfetto::protos::pbzero::TraceConfig_TraceFilter;
  using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
  using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
  using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
  static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
  static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
  static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
  static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
  static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
  static const StatsdLogging STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
  static const StatsdLogging STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
  static const StatsdLogging STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;

  using FieldMetadata_Buffers =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_BufferConfig,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Buffers kBuffers() { return {}; }
  template <typename T = TraceConfig_BufferConfig> T* add_buffers() {
    return BeginNestedMessage<T>(1);
  }


  using FieldMetadata_DataSources =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_DataSource,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
  template <typename T = TraceConfig_DataSource> T* add_data_sources() {
    return BeginNestedMessage<T>(2);
  }


  using FieldMetadata_BuiltinDataSources =
    ::protozero::proto_utils::FieldMetadata<
      20,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_BuiltinDataSource,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources() { return {}; }
  template <typename T = TraceConfig_BuiltinDataSource> T* set_builtin_data_sources() {
    return BeginNestedMessage<T>(20);
  }


  using FieldMetadata_DurationMs =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DurationMs kDurationMs() { return {}; }
  void set_duration_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_DurationMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_EnableExtraGuardrails =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
  void set_enable_extra_guardrails(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_EnableExtraGuardrails::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_LockdownMode =
    ::protozero::proto_utils::FieldMetadata<
      5,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_LockdownMode kLockdownMode() { return {}; }
  void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
    static constexpr uint32_t field_id = FieldMetadata_LockdownMode::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_Producers =
    ::protozero::proto_utils::FieldMetadata<
      6,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_ProducerConfig,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Producers kProducers() { return {}; }
  template <typename T = TraceConfig_ProducerConfig> T* add_producers() {
    return BeginNestedMessage<T>(6);
  }


  using FieldMetadata_StatsdMetadata =
    ::protozero::proto_utils::FieldMetadata<
      7,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_StatsdMetadata,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata() { return {}; }
  template <typename T = TraceConfig_StatsdMetadata> T* set_statsd_metadata() {
    return BeginNestedMessage<T>(7);
  }


  using FieldMetadata_WriteIntoFile =
    ::protozero::proto_utils::FieldMetadata<
      8,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile() { return {}; }
  void set_write_into_file(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_WriteIntoFile::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_OutputPath =
    ::protozero::proto_utils::FieldMetadata<
      29,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_OutputPath kOutputPath() { return {}; }
  void set_output_path(const char* data, size_t size) {
    AppendBytes(FieldMetadata_OutputPath::kFieldId, data, size);
  }
  void set_output_path(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_OutputPath::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_FileWritePeriodMs =
    ::protozero::proto_utils::FieldMetadata<
      9,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs() { return {}; }
  void set_file_write_period_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_FileWritePeriodMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_MaxFileSizeBytes =
    ::protozero::proto_utils::FieldMetadata<
      10,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint64,
      uint64_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes() { return {}; }
  void set_max_file_size_bytes(uint64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_MaxFileSizeBytes::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint64>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_GuardrailOverrides =
    ::protozero::proto_utils::FieldMetadata<
      11,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_GuardrailOverrides,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides() { return {}; }
  template <typename T = TraceConfig_GuardrailOverrides> T* set_guardrail_overrides() {
    return BeginNestedMessage<T>(11);
  }


  using FieldMetadata_DeferredStart =
    ::protozero::proto_utils::FieldMetadata<
      12,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DeferredStart kDeferredStart() { return {}; }
  void set_deferred_start(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_DeferredStart::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_FlushPeriodMs =
    ::protozero::proto_utils::FieldMetadata<
      13,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs() { return {}; }
  void set_flush_period_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_FlushPeriodMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_FlushTimeoutMs =
    ::protozero::proto_utils::FieldMetadata<
      14,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs() { return {}; }
  void set_flush_timeout_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_FlushTimeoutMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_DataSourceStopTimeoutMs =
    ::protozero::proto_utils::FieldMetadata<
      23,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs() { return {}; }
  void set_data_source_stop_timeout_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_DataSourceStopTimeoutMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_NotifyTraceur =
    ::protozero::proto_utils::FieldMetadata<
      16,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur() { return {}; }
  void set_notify_traceur(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_NotifyTraceur::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_BugreportScore =
    ::protozero::proto_utils::FieldMetadata<
      30,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt32,
      int32_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_BugreportScore kBugreportScore() { return {}; }
  void set_bugreport_score(int32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_BugreportScore::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TriggerConfig =
    ::protozero::proto_utils::FieldMetadata<
      17,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_TriggerConfig,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggerConfig kTriggerConfig() { return {}; }
  template <typename T = TraceConfig_TriggerConfig> T* set_trigger_config() {
    return BeginNestedMessage<T>(17);
  }


  using FieldMetadata_ActivateTriggers =
    ::protozero::proto_utils::FieldMetadata<
      18,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ActivateTriggers kActivateTriggers() { return {}; }
  void add_activate_triggers(const char* data, size_t size) {
    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, size);
  }
  void add_activate_triggers(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_ActivateTriggers::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_IncrementalStateConfig =
    ::protozero::proto_utils::FieldMetadata<
      21,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_IncrementalStateConfig,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig() { return {}; }
  template <typename T = TraceConfig_IncrementalStateConfig> T* set_incremental_state_config() {
    return BeginNestedMessage<T>(21);
  }


  using FieldMetadata_AllowUserBuildTracing =
    ::protozero::proto_utils::FieldMetadata<
      19,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing() { return {}; }
  void set_allow_user_build_tracing(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_AllowUserBuildTracing::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_UniqueSessionName =
    ::protozero::proto_utils::FieldMetadata<
      22,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName() { return {}; }
  void set_unique_session_name(const char* data, size_t size) {
    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
  }
  void set_unique_session_name(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_UniqueSessionName::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_CompressionType =
    ::protozero::proto_utils::FieldMetadata<
      24,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::TraceConfig_CompressionType,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_CompressionType kCompressionType() { return {}; }
  void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
    static constexpr uint32_t field_id = FieldMetadata_CompressionType::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_IncidentReportConfig =
    ::protozero::proto_utils::FieldMetadata<
      25,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_IncidentReportConfig,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig() { return {}; }
  template <typename T = TraceConfig_IncidentReportConfig> T* set_incident_report_config() {
    return BeginNestedMessage<T>(25);
  }


  using FieldMetadata_StatsdLogging =
    ::protozero::proto_utils::FieldMetadata<
      31,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::TraceConfig_StatsdLogging,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_StatsdLogging kStatsdLogging() { return {}; }
  void set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
    static constexpr uint32_t field_id = FieldMetadata_StatsdLogging::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TraceUuidMsb =
    ::protozero::proto_utils::FieldMetadata<
      27,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt64,
      int64_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb() { return {}; }
  void set_trace_uuid_msb(int64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TraceUuidMsb::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt64>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TraceUuidLsb =
    ::protozero::proto_utils::FieldMetadata<
      28,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt64,
      int64_t,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb() { return {}; }
  void set_trace_uuid_lsb(int64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TraceUuidLsb::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt64>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TraceFilter =
    ::protozero::proto_utils::FieldMetadata<
      33,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_TraceFilter,
      TraceConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TraceFilter kTraceFilter() { return {}; }
  template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
    return BeginNestedMessage<T>(33);
  }

};

class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_TraceFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_TraceFilter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_TraceFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_bytecode() const { return at<1>().valid(); }
  ::protozero::ConstBytes bytecode() const { return at<1>().as_bytes(); }
};

class TraceConfig_TraceFilter : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_TraceFilter_Decoder;
  enum : int32_t {
    kBytecodeFieldNumber = 1,
  };

  using FieldMetadata_Bytecode =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBytes,
      std::string,
      TraceConfig_TraceFilter>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Bytecode kBytecode() { return {}; }
  void set_bytecode(const uint8_t* data, size_t size) {
    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
  }
  void set_bytecode(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_Bytecode::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBytes>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_IncidentReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_IncidentReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_IncidentReportConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_IncidentReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_destination_package() const { return at<1>().valid(); }
  ::protozero::ConstChars destination_package() const { return at<1>().as_string(); }
  bool has_destination_class() const { return at<2>().valid(); }
  ::protozero::ConstChars destination_class() const { return at<2>().as_string(); }
  bool has_privacy_level() const { return at<3>().valid(); }
  int32_t privacy_level() const { return at<3>().as_int32(); }
  bool has_skip_incidentd() const { return at<5>().valid(); }
  bool skip_incidentd() const { return at<5>().as_bool(); }
  bool has_skip_dropbox() const { return at<4>().valid(); }
  bool skip_dropbox() const { return at<4>().as_bool(); }
};

class TraceConfig_IncidentReportConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_IncidentReportConfig_Decoder;
  enum : int32_t {
    kDestinationPackageFieldNumber = 1,
    kDestinationClassFieldNumber = 2,
    kPrivacyLevelFieldNumber = 3,
    kSkipIncidentdFieldNumber = 5,
    kSkipDropboxFieldNumber = 4,
  };

  using FieldMetadata_DestinationPackage =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_IncidentReportConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DestinationPackage kDestinationPackage() { return {}; }
  void set_destination_package(const char* data, size_t size) {
    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, size);
  }
  void set_destination_package(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_DestinationPackage::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_DestinationClass =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_IncidentReportConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DestinationClass kDestinationClass() { return {}; }
  void set_destination_class(const char* data, size_t size) {
    AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, size);
  }
  void set_destination_class(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_DestinationClass::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_PrivacyLevel =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt32,
      int32_t,
      TraceConfig_IncidentReportConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel() { return {}; }
  void set_privacy_level(int32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_PrivacyLevel::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_SkipIncidentd =
    ::protozero::proto_utils::FieldMetadata<
      5,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_IncidentReportConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd() { return {}; }
  void set_skip_incidentd(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_SkipIncidentd::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_SkipDropbox =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_IncidentReportConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_SkipDropbox kSkipDropbox() { return {}; }
  void set_skip_dropbox(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_SkipDropbox::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_IncrementalStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_IncrementalStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_IncrementalStateConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_IncrementalStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_clear_period_ms() const { return at<1>().valid(); }
  uint32_t clear_period_ms() const { return at<1>().as_uint32(); }
};

class TraceConfig_IncrementalStateConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_IncrementalStateConfig_Decoder;
  enum : int32_t {
    kClearPeriodMsFieldNumber = 1,
  };

  using FieldMetadata_ClearPeriodMs =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_IncrementalStateConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs() { return {}; }
  void set_clear_period_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_ClearPeriodMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_TriggerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
 public:
  TraceConfig_TriggerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_TriggerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_TriggerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_trigger_mode() const { return at<1>().valid(); }
  int32_t trigger_mode() const { return at<1>().as_int32(); }
  bool has_triggers() const { return at<2>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> triggers() const { return GetRepeated<::protozero::ConstBytes>(2); }
  bool has_trigger_timeout_ms() const { return at<3>().valid(); }
  uint32_t trigger_timeout_ms() const { return at<3>().as_uint32(); }
};

class TraceConfig_TriggerConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_TriggerConfig_Decoder;
  enum : int32_t {
    kTriggerModeFieldNumber = 1,
    kTriggersFieldNumber = 2,
    kTriggerTimeoutMsFieldNumber = 3,
  };
  using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
  using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
  static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
  static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
  static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;

  using FieldMetadata_TriggerMode =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode,
      TraceConfig_TriggerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggerMode kTriggerMode() { return {}; }
  void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggerMode::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_Triggers =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      TraceConfig_TriggerConfig_Trigger,
      TraceConfig_TriggerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Triggers kTriggers() { return {}; }
  template <typename T = TraceConfig_TriggerConfig_Trigger> T* add_triggers() {
    return BeginNestedMessage<T>(2);
  }


  using FieldMetadata_TriggerTimeoutMs =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_TriggerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs() { return {}; }
  void set_trigger_timeout_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggerTimeoutMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_TriggerConfig_Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_TriggerConfig_Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_TriggerConfig_Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_name() const { return at<1>().valid(); }
  ::protozero::ConstChars name() const { return at<1>().as_string(); }
  bool has_producer_name_regex() const { return at<2>().valid(); }
  ::protozero::ConstChars producer_name_regex() const { return at<2>().as_string(); }
  bool has_stop_delay_ms() const { return at<3>().valid(); }
  uint32_t stop_delay_ms() const { return at<3>().as_uint32(); }
  bool has_max_per_24_h() const { return at<4>().valid(); }
  uint32_t max_per_24_h() const { return at<4>().as_uint32(); }
  bool has_skip_probability() const { return at<5>().valid(); }
  double skip_probability() const { return at<5>().as_double(); }
};

class TraceConfig_TriggerConfig_Trigger : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_TriggerConfig_Trigger_Decoder;
  enum : int32_t {
    kNameFieldNumber = 1,
    kProducerNameRegexFieldNumber = 2,
    kStopDelayMsFieldNumber = 3,
    kMaxPer24HFieldNumber = 4,
    kSkipProbabilityFieldNumber = 5,
  };

  using FieldMetadata_Name =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_TriggerConfig_Trigger>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Name kName() { return {}; }
  void set_name(const char* data, size_t size) {
    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
  }
  void set_name(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_ProducerNameRegex =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_TriggerConfig_Trigger>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex() { return {}; }
  void set_producer_name_regex(const char* data, size_t size) {
    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, size);
  }
  void set_producer_name_regex(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegex::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_StopDelayMs =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_TriggerConfig_Trigger>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_StopDelayMs kStopDelayMs() { return {}; }
  void set_stop_delay_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_StopDelayMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_MaxPer24H =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_TriggerConfig_Trigger>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_MaxPer24H kMaxPer24H() { return {}; }
  void set_max_per_24_h(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_MaxPer24H::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_SkipProbability =
    ::protozero::proto_utils::FieldMetadata<
      5,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kDouble,
      double,
      TraceConfig_TriggerConfig_Trigger>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_SkipProbability kSkipProbability() { return {}; }
  void set_skip_probability(double value) {
    static constexpr uint32_t field_id = FieldMetadata_SkipProbability::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kDouble>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_GuardrailOverrides_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_GuardrailOverrides_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_GuardrailOverrides_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_GuardrailOverrides_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_max_upload_per_day_bytes() const { return at<1>().valid(); }
  uint64_t max_upload_per_day_bytes() const { return at<1>().as_uint64(); }
};

class TraceConfig_GuardrailOverrides : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_GuardrailOverrides_Decoder;
  enum : int32_t {
    kMaxUploadPerDayBytesFieldNumber = 1,
  };

  using FieldMetadata_MaxUploadPerDayBytes =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint64,
      uint64_t,
      TraceConfig_GuardrailOverrides>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes() { return {}; }
  void set_max_upload_per_day_bytes(uint64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_MaxUploadPerDayBytes::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint64>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_StatsdMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_StatsdMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_StatsdMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_StatsdMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_triggering_alert_id() const { return at<1>().valid(); }
  int64_t triggering_alert_id() const { return at<1>().as_int64(); }
  bool has_triggering_config_uid() const { return at<2>().valid(); }
  int32_t triggering_config_uid() const { return at<2>().as_int32(); }
  bool has_triggering_config_id() const { return at<3>().valid(); }
  int64_t triggering_config_id() const { return at<3>().as_int64(); }
  bool has_triggering_subscription_id() const { return at<4>().valid(); }
  int64_t triggering_subscription_id() const { return at<4>().as_int64(); }
};

class TraceConfig_StatsdMetadata : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_StatsdMetadata_Decoder;
  enum : int32_t {
    kTriggeringAlertIdFieldNumber = 1,
    kTriggeringConfigUidFieldNumber = 2,
    kTriggeringConfigIdFieldNumber = 3,
    kTriggeringSubscriptionIdFieldNumber = 4,
  };

  using FieldMetadata_TriggeringAlertId =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt64,
      int64_t,
      TraceConfig_StatsdMetadata>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId() { return {}; }
  void set_triggering_alert_id(int64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggeringAlertId::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt64>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TriggeringConfigUid =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt32,
      int32_t,
      TraceConfig_StatsdMetadata>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid() { return {}; }
  void set_triggering_config_uid(int32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigUid::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TriggeringConfigId =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt64,
      int64_t,
      TraceConfig_StatsdMetadata>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId() { return {}; }
  void set_triggering_config_id(int64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigId::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt64>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_TriggeringSubscriptionId =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kInt64,
      int64_t,
      TraceConfig_StatsdMetadata>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId() { return {}; }
  void set_triggering_subscription_id(int64_t value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggeringSubscriptionId::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kInt64>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_ProducerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_ProducerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_ProducerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_ProducerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_producer_name() const { return at<1>().valid(); }
  ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
  bool has_shm_size_kb() const { return at<2>().valid(); }
  uint32_t shm_size_kb() const { return at<2>().as_uint32(); }
  bool has_page_size_kb() const { return at<3>().valid(); }
  uint32_t page_size_kb() const { return at<3>().as_uint32(); }
};

class TraceConfig_ProducerConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_ProducerConfig_Decoder;
  enum : int32_t {
    kProducerNameFieldNumber = 1,
    kShmSizeKbFieldNumber = 2,
    kPageSizeKbFieldNumber = 3,
  };

  using FieldMetadata_ProducerName =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_ProducerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
  void set_producer_name(const char* data, size_t size) {
    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
  }
  void set_producer_name(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_ShmSizeKb =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_ProducerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ShmSizeKb kShmSizeKb() { return {}; }
  void set_shm_size_kb(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_ShmSizeKb::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_PageSizeKb =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_ProducerConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_PageSizeKb kPageSizeKb() { return {}; }
  void set_page_size_kb(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_PageSizeKb::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_BuiltinDataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_BuiltinDataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_BuiltinDataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_BuiltinDataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_disable_clock_snapshotting() const { return at<1>().valid(); }
  bool disable_clock_snapshotting() const { return at<1>().as_bool(); }
  bool has_disable_trace_config() const { return at<2>().valid(); }
  bool disable_trace_config() const { return at<2>().as_bool(); }
  bool has_disable_system_info() const { return at<3>().valid(); }
  bool disable_system_info() const { return at<3>().as_bool(); }
  bool has_disable_service_events() const { return at<4>().valid(); }
  bool disable_service_events() const { return at<4>().as_bool(); }
  bool has_primary_trace_clock() const { return at<5>().valid(); }
  int32_t primary_trace_clock() const { return at<5>().as_int32(); }
  bool has_snapshot_interval_ms() const { return at<6>().valid(); }
  uint32_t snapshot_interval_ms() const { return at<6>().as_uint32(); }
  bool has_prefer_suspend_clock_for_snapshot() const { return at<7>().valid(); }
  bool prefer_suspend_clock_for_snapshot() const { return at<7>().as_bool(); }
};

class TraceConfig_BuiltinDataSource : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_BuiltinDataSource_Decoder;
  enum : int32_t {
    kDisableClockSnapshottingFieldNumber = 1,
    kDisableTraceConfigFieldNumber = 2,
    kDisableSystemInfoFieldNumber = 3,
    kDisableServiceEventsFieldNumber = 4,
    kPrimaryTraceClockFieldNumber = 5,
    kSnapshotIntervalMsFieldNumber = 6,
    kPreferSuspendClockForSnapshotFieldNumber = 7,
  };

  using FieldMetadata_DisableClockSnapshotting =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting() { return {}; }
  void set_disable_clock_snapshotting(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_DisableClockSnapshotting::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_DisableTraceConfig =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig() { return {}; }
  void set_disable_trace_config(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_DisableTraceConfig::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_DisableSystemInfo =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo() { return {}; }
  void set_disable_system_info(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_DisableSystemInfo::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_DisableServiceEvents =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents() { return {}; }
  void set_disable_service_events(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_DisableServiceEvents::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_PrimaryTraceClock =
    ::protozero::proto_utils::FieldMetadata<
      5,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::BuiltinClock,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
  void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
    static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_SnapshotIntervalMs =
    ::protozero::proto_utils::FieldMetadata<
      6,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs() { return {}; }
  void set_snapshot_interval_ms(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_SnapshotIntervalMs::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_PreferSuspendClockForSnapshot =
    ::protozero::proto_utils::FieldMetadata<
      7,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kBool,
      bool,
      TraceConfig_BuiltinDataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot() { return {}; }
  void set_prefer_suspend_clock_for_snapshot(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForSnapshot::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kBool>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
 public:
  TraceConfig_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_DataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_config() const { return at<1>().valid(); }
  ::protozero::ConstBytes config() const { return at<1>().as_bytes(); }
  bool has_producer_name_filter() const { return at<2>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_filter() const { return GetRepeated<::protozero::ConstChars>(2); }
  bool has_producer_name_regex_filter() const { return at<3>().valid(); }
  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_regex_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
};

class TraceConfig_DataSource : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_DataSource_Decoder;
  enum : int32_t {
    kConfigFieldNumber = 1,
    kProducerNameFilterFieldNumber = 2,
    kProducerNameRegexFilterFieldNumber = 3,
  };

  using FieldMetadata_Config =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kMessage,
      DataSourceConfig,
      TraceConfig_DataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_Config kConfig() { return {}; }
  template <typename T = DataSourceConfig> T* set_config() {
    return BeginNestedMessage<T>(1);
  }


  using FieldMetadata_ProducerNameFilter =
    ::protozero::proto_utils::FieldMetadata<
      2,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_DataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter() { return {}; }
  void add_producer_name_filter(const char* data, size_t size) {
    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, size);
  }
  void add_producer_name_filter(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_ProducerNameFilter::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_ProducerNameRegexFilter =
    ::protozero::proto_utils::FieldMetadata<
      3,
      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
      ::protozero::proto_utils::ProtoSchemaType::kString,
      std::string,
      TraceConfig_DataSource>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter() { return {}; }
  void add_producer_name_regex_filter(const char* data, size_t size) {
    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, size);
  }
  void add_producer_name_regex_filter(std::string value) {
    static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegexFilter::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kString>
        ::Append(*this, field_id, value);
  }
};

class TraceConfig_BufferConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 public:
  TraceConfig_BufferConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
  explicit TraceConfig_BufferConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
  explicit TraceConfig_BufferConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
  bool has_size_kb() const { return at<1>().valid(); }
  uint32_t size_kb() const { return at<1>().as_uint32(); }
  bool has_fill_policy() const { return at<4>().valid(); }
  int32_t fill_policy() const { return at<4>().as_int32(); }
};

class TraceConfig_BufferConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_BufferConfig_Decoder;
  enum : int32_t {
    kSizeKbFieldNumber = 1,
    kFillPolicyFieldNumber = 4,
  };
  using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
  static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
  static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
  static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;

  using FieldMetadata_SizeKb =
    ::protozero::proto_utils::FieldMetadata<
      1,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kUint32,
      uint32_t,
      TraceConfig_BufferConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
  void set_size_kb(uint32_t value) {
    static constexpr uint32_t field_id = FieldMetadata_SizeKb::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kUint32>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_FillPolicy =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::protozero::proto_utils::RepetitionType::kNotRepeated,
      ::protozero::proto_utils::ProtoSchemaType::kEnum,
      ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy,
      TraceConfig_BufferConfig>;

  // Ceci n'est pas une pipe.
  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
  // type (and users are expected to use it as such, hence kCamelCase name).
  // It is declared as a function to keep protozero bindings header-only as
  // inline constexpr variables are not available until C++17 (while inline
  // functions are).
  // TODO(altimin): Use inline variable instead after adopting C++17.  
  static constexpr FieldMetadata_FillPolicy kFillPolicy() { return {}; }
  void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
    static constexpr uint32_t field_id = FieldMetadata_FillPolicy::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }
};

} // Namespace.
} // Namespace.
} // Namespace.
#endif  // Include guard.
